एक ही चयन सूची में संदर्भ स्तंभ उपनाम


27

मैं एक पुराना MS-Access-आधारित सिस्टम PostgreSQL में परिवर्तित कर रहा हूँ। पहुँच में, फ़ील्ड जो SELECT में बनाए गए थे, उन्हें बाद के क्षेत्रों के समीकरणों के भागों के रूप में इस्तेमाल किया जा सकता है, जैसे:

SELECT
    samples.id,
    samples.wet_weight / samples.dry_weight - 1 AS percent_water,
    100 * percent_water AS percent_water_100
FROM samples;

जब मैं PostgreSQL में ऐसा करता हूं, तो Postgres एक त्रुटि फेंकता है:

त्रुटि: कॉलम "प्रतिशत_ वाटर" मौजूद नहीं है।

यहां बताया गया है कि उप-चयन से बाहर निकलकर मैं इसके चारों ओर कैसे काम कर सकता हूं:

SELECT
    s1.id,
    s1.percent_water,
    100 * s1.percent_water AS percent_water_100
FROM (
    SELECT
        samples.id,
        samples.wet_weight / samples.dry_weight - 1 AS percent_water
    FROM samples
    ) s1;

क्या जटिल घोंसले के शिकार होने के लिए पहले कोड ब्लॉक में किसी तरह का शॉर्टकट है? मैं यह भी कह सकता हूं 100 * (samples.wet_weight / samples.dry_weight - 1) AS percent_water_100, लेकिन यह सिर्फ एक छोटा सा उदाहरण है कि मेरे कोड में गणित की एक बहुत बड़ी प्रणाली क्या चल रही है, गणित के दर्जनों और अधिक जटिल बिट्स एक दूसरे के ऊपर ढेर हो गए हैं। मैं खुद को दोहराए बिना यथासंभव सफाई से करना पसंद करूंगा।

जवाबों:


24

यह कभी-कभी असुविधाजनक होता है, लेकिन यह SQL मानक व्यवहार है, और यह अस्पष्टता को रोकता है। आप समान SELECTसूची में कॉलम उपनामों का संदर्भ नहीं दे सकते ।

छोटे वाक्यविन्यास विकल्प हैं:

SELECT s.*, s.percent_water * 100 AS percent_water_100
FROM  (
   SELECT id, wet_weight / NULLIF(dry_weight - 1, 0) AS percent_water
   FROM   samples
   ) s;

और आप LATERALPostgres 9.3+ में शामिल हो सकते हैं :

SELECT s.id, s1.percent_water
     , s1.percent_water * 100 AS percent_water_100
FROM   samples s
     , LATERAL (SELECT s.wet_weight / NULLIF(s.dry_weight - 1, 0) AS percent_water) s1;

मैंने NULLIF()विभाजन-दर-शून्य त्रुटियों से बचाव करने के लिए जोड़ा ।


2
नमस्ते। क्या आप अपने उत्तर को एक उदाहरण द्वारा विस्तारित कर सकते हैं जो एसक्यूएल फरिश्ता को रोकता है?
यूजेन कोनकोव

4

मैं इस तरह से कुछ हिट करता हूं कि SQL सर्वर पर 500+ लाइन Netezza क्वेरी (उर्फ संशोधित पोस्टग्रेज) माइग्रेट करता है। नेटिज़्जा में गणना किए गए स्तंभ उपनाम को डाउनस्ट्रीम संदर्भों में एक मूल्य के रूप में उपयोग करने की अनुमति दी गई थी।

मेरे काम के आसपास एक सह-उप-क्वेरी के साथ CROSS APPLY का उपयोग करना था। इसकी सुंदरता यह है कि मूल क्वेरी में कॉलम उर्फ ​​के कई संदर्भों को बिल्कुल भी बदलने की आवश्यकता नहीं है।

ओपी से क्वेरी का उपयोग करते हुए, CROSS APPLYविधि कुछ इस तरह दिखाई देगी:

SELECT
    s.id,
    x.percent_water,
    100 * x.percent_water AS percent_water_100
FROM samples AS s
CROSS APPLY (SELECT s.wet_weight / s.dry_weight - 1 AS percent_water ) x ;

1
CROSS APPLY(और OUTER APPLY) LATERALसबवेरीज़ लिखने का SQL सर्वर तरीका है ।
ypercube y

4
cross applyPostgres में कोई नहीं है। मानक से चिपक जाता है और उपयोग करता है cross join lateral
a_horse_with_no_name
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.