87

私はこのようなクエリを持っています:

SELECT
    jobs.*, 
    (
        CASE
            WHEN lead_informations.state IS NOT NULL THEN lead_informations.state
            ELSE 'NEW'
        END
    ) AS lead_state
FROM
    jobs
    LEFT JOIN lead_informations ON
        lead_informations.job_id = jobs.id
        AND
        lead_informations.mechanic_id = 3
WHERE
    lead_state = 'NEW'

これにより、次のエラーが発生します。

PGError: ERROR:  column "lead_state" does not exist
LINE 1: ...s.id AND lead_informations.mechanic_id = 3 WHERE (lead_state...

MySqlではこれは有効ですが、Postgresqlでは明らかにそうではありません。私が収集できることから、その理由はSELECT、クエリの一部がその部分よりも後で評価されるためですWHERE。この問題の一般的な回避策はありますか?

4

6 に答える 6

88

私は同じ問題に苦労しました、そして「mysql構文は非標準です」は私の意見では有効な議論ではありません。PostgreSQLは、便利な非標準の拡張機能も追加します。たとえば、「INSERT ... RETURNING ...」は、挿入後に自動IDを取得します。また、大規模なクエリを繰り返すことは、洗練されたソリューションではありません。

ただし、WITHステートメントは非常に役立ちました(CTEの場合)。クエリ内に一時的なビューを作成し、通常のテーブルのように使用できます。JOINを正しく書き直したかどうかはわかりませんが、一般的には次のように機能するはずです。

WITH jobs_refined AS (
    SELECT
        jobs.*,
        (SELECT CASE WHEN lead_informations.state IS NOT NULL THEN lead_informations.state ELSE 'NEW' END) AS lead_state
    FROM jobs
    LEFT JOIN lead_informations
        ON lead_informations.job_id = jobs.id
        AND lead_informations.mechanic_id = 3
)
SELECT *
FROM jobs_refined
WHERE lead_state = 'NEW'
于 2011-11-11T14:32:54.000 に答える
24

where句のcaseステートメントを複製する必要があるか、私の好みは次のようなことをすることです。

SELECT *
FROM (
  SELECT 
      jobs.*, 
      (CASE WHEN lead_informations.state IS NOT NULL THEN lead_informations.state ELSE 'NEW' END) as lead_state
  FROM 
      "jobs"
      LEFT JOIN lead_informations ON lead_informations.job_id = jobs.id
      AND lead_informations.mechanic_id = 3
) q1
WHERE (lead_state = 'NEW')
于 2012-10-12T19:50:34.290 に答える
17

あなたが経験したように、MySQLのサポートは非​​標準です。正しい方法は、SELECT句で使用されているのと同じ式を再印刷することです。

SELECT
    jobs.*, 
    CASE 
         WHEN lead_informations.state IS NOT NULL THEN lead_informations.state 
         ELSE 'NEW' 
    END AS lead_state
FROM
    jobs
    LEFT JOIN lead_informations ON
        lead_informations.job_id = jobs.id
        AND
        lead_informations.mechanic_id = 3
WHERE
    lead_informations.state IS NULL
于 2010-07-13T20:46:35.880 に答える
3

一般的な解決策は、計算に内部SELECT(この場合はCASEステートメント)を使用して、実行がそのクエリに到達するまでに内部SELECTの結果を外部クエリ全体で利用できるようにすることだと思います。それ以外の場合、WHERE句が最初に評価され、SELECT句については何も知りません。

于 2010-07-13T20:46:36.123 に答える
0

私はこのような場所でエイリアスを使用しました。(サブクエリ)。

Select "Vendors"."VendorId", "Vendors"."Name","Result"."Total" 
From (Select "Trans"."VendorId", ("Trans"."A"+"Trans"."B"+"Trans"."C")    AS "Total"
        FROM "Trans"
    WHERE "Trans"."Year"=2014                                                
    ) As "Result"
JOIN "Vendors" ON "Result"."VendorId"="Vendors"."VendorId" 
WHERE "Vendors"."Class"='I' AND "Result"."Total" > 200
于 2015-10-08T10:27:11.260 に答える
0

サブクエリ:

SELECT "tab_1"."BirthDate", "tab_1"."col_1" FROM (
   SELECT BirthDate, DATEADD(year, 18, BirthDate) AS "col_1" FROM Employees
) AS "tab_1"
WHERE "tab_1"."col_1" >= '2000-12-31';
于 2019-04-10T20:46:07.107 に答える