93 votes

Utilisation d'une colonne Alias dans la clause where de Postgresql

J'ai une requête comme celle-ci :

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'

Ce qui donne l'erreur suivante :

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

Dans MySql, cela est valide, mais apparemment pas dans Postgresql. D'après ce que je peux recueillir, la raison est que la partie SELECT de la requête est évaluée plus tard que la partie WHERE. Y a-t-il une solution commune à ce problème ?

26voto

mrSpear Points 81

Vous auriez besoin de dupliquer l'énoncé de cas dans la clause where, ou ma préférence est de faire quelque chose comme ceci :

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

17voto

OMG Ponies Points 144785

Le support de MySQL est, comme vous l'avez vécu, non standard. La bonne façon est de réimprimer la même expression utilisée dans la clause 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

3voto

David Points 65209

Je crois que la solution courante est d'utiliser une SÉLECTION interne pour le calcul (ou l'instruction CASE dans ce cas) afin que le résultat de la SÉLECTION interne soit disponible pour l'ensemble de la requête externe au moment où l'exécution arrive à cette requête. Sinon, la clause WHERE est évaluée en premier et ne connaît rien de la clause SELECT.

0voto

M Sohail Maroof Points 13

J'ai utilisé un alias comme ça. (Sous-requête).

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X