2010-07-13 7 views
40

में जहां खंड में एक अन्य नाम स्तंभ का उपयोग करते हुए मैं इस तरह एक प्रश्न हैPostgresql

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 भाग के बाद मूल्यांकन किया जाता है। क्या इस समस्या के लिए कोई आम कामकाज है?

+0

मुझे लगता है कि इस PostgreSQL में मान्य नहीं है ... – pcent

+1

@pcent कि त्रुटि तो समझा जाएगा ... – troelskn

+0

यह एक अच्छा सवाल है, लेकिन एक विचित्र उदाहरण क्वेरी। आप कभी भी उस कॉलम के लिए गैर-नूल मान का चयन नहीं करना चाहते हैं, इसलिए पूरा केस स्टेटमेंट पूरी तरह से अनावश्यक है। – phils

उत्तर

11

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 
+3

इसके अतिरिक्त, आप CASEESCE के साथ CASE कथन को प्रतिस्थापित कर सकते हैं: 'COALESCE (lead_informations.state, 'NEW') AS lead_state'। –

+3

इस तरह के तर्क को डुप्लिकेट करने के लिए थोड़ा अजीब लगता है, लेकिन मुझे लगता है कि मैं बस ऐसा करूँगा। 'COALESCE' के बारे में नहीं पता था - उस टिप के लिए धन्यवाद। – troelskn

0

मेरा मानना ​​है कि आम समाधान गणना (या इस मामले में मामला बयान) के लिए एक आंतरिक चयन का उपयोग करना है का परिणाम उस क्वेरी को निष्पादन के समय तक आंतरिक बाहरी क्वेरी में आंतरिक चयन उपलब्ध है। अन्यथा, WHERE खंड का मूल्यांकन पहले किया जाता है और चयन खंड के बारे में कुछ भी नहीं जानता है।

40

मैंने एक ही मुद्दे पर संघर्ष किया और "mysql वाक्यविन्यास गैर मानक" मेरी राय में एक वैध तर्क नहीं है। पोस्टग्रेएसक्यूएल आसान गैर मानक एक्सटेंशन भी जोड़ता है, उदाहरण के लिए "INSERT ... वापसी ..." प्रविष्टियों के बाद ऑटो आईडी प्राप्त करने के लिए। इसके अलावा, बड़े प्रश्नों को दोहराना एक सुरुचिपूर्ण समाधान नहीं है।

हालांकि, मुझे WITH statement बहुत उपयोगी मिला। यह प्रकार क्वेरी के भीतर अस्थायी दृश्य बनाता है जिसे आप सामान्य तालिका की तरह उपयोग कर सकते हैं। मुझे यकीन है कि अगर मैं अपने को सही ढंग से शामिल हों फिर से लिखा है नहीं कर रहा हूँ, लेकिन सामान्य रूप में यह इस तरह काम करना चाहिए:

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' 
+12

कह रहा है कि कुछ "गैर-मानक" पूरी तरह मान्य है जब आप दो अलग-अलग उत्पादों में कुछ करना चाहते हैं। वे दोनों एसक्यूएल मानक के हिस्सों को लागू करते हैं और दोनों में गैर-मानक एक्सटेंशन होते हैं। गैर-मानक एक्सटेंशन का अनुवाद करने की अपेक्षा न करें। एसक्यूएल मानक भागों का अनुवाद करने की उम्मीद है। कहा जा रहा है - उदाहरण के लिए धन्यवाद। – Messy

+1

मानक में एक बात कहने पर भी एक अंतर होता है, और आप उस उत्पाद के लिए कुछ और बनाम एक्सटेंशन करते हैं जहां मानक चुप है। –

15

आप या तो जहां खंड में मामले बयान नकल करने की आवश्यकता होगी, या मेरी प्राथमिकता कुछ करने के लिए है निम्न की तरह:

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

मैंने इस तरह के उपनाम का उपयोग किया। (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