Program Tip

Postgresql의 where 절에서 별칭 열 사용

programtip 2020. 12. 8. 19:50
반응형

Postgresql의 where 절에서 별칭 열 사용


다음과 같은 쿼리가 있습니다.

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부분 부분 보다 늦게 평가되기 때문 입니다. 이 문제에 대한 일반적인 해결 방법이 있습니까?


경험했듯이 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

나는 같은 문제로 고생했고 "mysql 구문은 비표준이다"는 내 의견으로는 유효한 주장이 아니다. PostgreSQL은 편리한 비표준 확장 기능도 추가합니다. 예를 들어 "INSERT ... RETURNING ..."은 삽입 후 자동 ID를 가져옵니다. 또한 큰 쿼리를 반복하는 것은 좋은 해결책이 아닙니다.

그러나 WITH 문이 매우 유용 하다는 것을 알았습니다 . 일종의 임시 뷰를 쿼리 내에 생성하여 일반적인 테이블처럼 사용할 수 있습니다. 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'

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')

일반적인 해결책은 계산 (또는이 경우 CASE 문)에 내부 SELECT를 사용하여 실행이 해당 쿼리에 도달 할 때까지 전체 외부 쿼리에서 내부 SELECT의 결과를 사용할 수 있도록하는 것입니다. 그렇지 않으면 WHERE 절이 먼저 평가되고 SELECT 절에 대해 알지 못합니다.


나는 이와 같은 곳에 별칭을 사용했습니다. (INNER 쿼리).

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

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

참고URL : https://stackoverflow.com/questions/3241352/using-an-alias-column-in-the-where-clause-in-postgresql

반응형