Обновить из выбора с помощью коррелированного подзапроса и присоединиться к PostgreSQL - PullRequest
0 голосов
/ 27 декабря 2018

Я перехожу с SQL Server на Postgres, и по большей части все прошло нормально.Одна из проблем заключается в том, что я не могу понять, как заставить этот запрос работать в Postgres:

update
    "Measure"
set 
    DefaultStrataId = StrataId

FROM (SELECT "Strata"."MeasureId",
               Min("Strata"."index") AS "Index"
        FROM   "Strata",
               "Measure"
        WHERE  "Strata"."MeasureId" = "Measure"."MeasureId" and "Strata"."StrataId" in (select strataid from point)
        GROUP  BY "Strata"."MeasureId") a
       INNER JOIN strata 
               ON "Strata"."index" = a."index"
               where "Strata"."MeasureId" = "Measure"."MeasureId";  

Он жалуется: SQL Error [42601]: ERROR: syntax error at or near "FROM"

Как мне заставить это работать?

Ответы [ 3 ]

0 голосов
/ 28 декабря 2018

фанки.После того, как @wildplasser почувствовал стыд за то, что мой запрос не отвратителен, все волшебным образом начало работать.Я не изменил ничего, кроме перехода на стандартные объединения и добавления псевдонимов:

update
    "Measure" m set
        "DefaultStrataId" = "StrataId"
    from
        (
        select
            s."MeasureId",
            min(s."Index") as "Index"
        from
            "Measure" m
        inner join "Strata" s on
            s."MeasureId" = m."MeasureId"
        where s."StrataId" in (
            select
                s."StrataId"
            from
                "Point")
        group by
            s."MeasureId") a
    inner join "Strata" s on
        s."Index" = a."Index"
    where
        s."MeasureId" = m."MeasureId";
0 голосов
/ 28 декабря 2018

Ваша единственная цель - получить минимальное значение от Strata

Пропустить все уродливые кавычки и добавить несколько псевдонимов (при условии, что существует только одна запись с минимальным значением):


UPDATE Measure m
SET    DefaultStrataId = s.StrataId
FROM   Strata s
WHERE  s.MeasureId = m.MeasureId
AND NOT EXISTS (
        SELECT * FROM Strata nx
        where nx.MeasureId = s.MeasureId  
        AND nx."index" < s."index"  
        )
        ;
0 голосов
/ 28 декабря 2018

Вы можете использовать DISTINCT ON для этого, чтобы упростить его.
ORDER BY в подзапросе удостоверится, что это "StrataId" для минимального "индекса".

UPDATE "Measure" m
SET "DefaultStrataId" = q."StrataId"
FROM
(
  SELECT DISTINCT ON (s."MeasureId") s."MeasureId", s."index", s."StrataId"
  FROM "Strata" s
  JOIN "Point" p ON p."StrataId" = s."StrataId"
  JOIN "Measure" m ON m."MeasureId" = s."MeasureId"
  ORDER BY s."MeasureId", s."index"
) q
WHERE q."MeasureId" = m."MeasureId";

Тест на db <> fiddle здесь

Кстати, приведенный ниже запрос также работает с тестовыми данными в этой скрипке.
По сути, в Postgresql цитирование имени не совпадает с цитированием имени.
MS Sql Server гораздо более терпим в этом аспекте.

UPDATE "Measure"
SET "DefaultStrataId" = "StrataId"
FROM (SELECT "Strata"."MeasureId",
               Min("Strata"."index") AS "index"
        FROM   "Strata",
               "Measure"
        WHERE  "Strata"."MeasureId" = "Measure"."MeasureId" and "Strata"."StrataId" in (select "StrataId" from "Point")
        GROUP  BY "Strata"."MeasureId") a
       INNER JOIN "Strata" 
               ON "Strata"."index" = a."index"
               where "Strata"."MeasureId" = "Measure"."MeasureId";
...