Update From Select with Correlated Subquery and Join in PostgreSQL

别说谁变了你拦得住时间么 提交于 2019-12-11 17:14:41

问题


I am migrating from SQL Server to Postgres and it has gone okay for the most part. One of the issues is that I am unable to figure out how to make this query work in 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";  

It complains: SQL Error [42601]: ERROR: syntax error at or near "FROM"

How do I get this to work?


回答1:


Funky. After feeling shamed by @wildplasser to make my query non-disgusting, everything magically started working. It's not like I changed anything except switching to standard joins and adding aliases:

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";



回答2:


You can use a DISTINCT ON for this to simplify it.
The ORDER BY in the sub-query will make sure that it's the "StrataId" for the minimum "index".

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";

Test on db<>fiddle here

Btw, the query below also works with the test data in that fiddle.
Basically, in Postgresql quoting a name isn't the same as not quoting a name.
MS Sql Server is much more tolerant in that aspect.

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";



回答3:


Your only goal appears to be getting the minimal value from Strata

Omitting all the ugly quotes,and adding some aliasses (assuming that only one record with the minumum value exists) :


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"  
        )
        ;


来源:https://stackoverflow.com/questions/53950599/update-from-select-with-correlated-subquery-and-join-in-postgresql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!