यदि लौटाया गया मान शून्य है, तो postgresql वापसी


99

मेरे पास एक क्वेरी है जो avg (मूल्य) लौटाती है

  select avg(price)
  from(
      select *, cume_dist() OVER (ORDER BY price desc) from web_price_scan
      where listing_Type='AARM'
        and u_kbalikepartnumbers_id = 1000307
        and (EXTRACT(Day FROM (Now()-dateEnded)))*24 < 48
        and price>( select avg(price)* 0.50
                    from(select *, cume_dist() OVER (ORDER BY price desc)
                         from web_price_scan
                         where listing_Type='AARM'
                           and u_kbalikepartnumbers_id = 1000307
                           and (EXTRACT(Day FROM (Now()-dateEnded)))*24 < 48
                        )g
                   where cume_dist < 0.50
                 )
        and price<( select avg(price)*2
                    from( select *, cume_dist() OVER (ORDER BY price desc)
                          from web_price_scan
                          where listing_Type='AARM'
                            and u_kbalikepartnumbers_id = 1000307
                            and (EXTRACT(Day FROM (Now()-dateEnded)))*24 < 48
                        )d
                    where cume_dist < 0.50)
     )s

  having count(*) > 5

यदि कोई मूल्य उपलब्ध नहीं है, तो इसे 0 कैसे करें?


1
क्या आप सुनिश्चित हैं कि आप क्वेरी अच्छी तरह से बना रहे हैं?
ल्यूक एम

2
@ ल्यूक: यह एक अच्छी तरह से बनाई गई क्वेरी नहीं हो सकती। ("खंड के बिना" समूह के बिना "होने")
माइक शेरिल 'कैट रिकॉल'

सब कुछ ठीक काम करता है, सिवाय इसके कि कभी-कभी, जब नियमों को पूरा नहीं किया जाता है, तो यह कुछ भी वापस नहीं करता है। इसके अलावा, मैं औसत से गोर कैसे हो सकता हूं, मुझे नहीं लगता कि यह संभव है? क्या बात है? एकाधिक चयन from web_price_scanअलग-अलग चयन हैं; सुनिश्चित नहीं है कि यहाँ क्या मुद्दा है?
एंड्रयू

यह havingएक group by(एक समूह के लिए चूक) के बिना एक खंड का उपयोग करने के लिए ठीक है । यह whereकुल परिणामों पर एक खंड के रूप में कार्य करता है । इस स्थिति में, पंक्तियों को केवल तब ही लौटाया जाता है जब 5 से अधिक पंक्तियों को 1 स्तर के उपवर्ग द्वारा लौटाया जाता है।
ब्रूस्कीस्की

जवाबों:


178

coalesce का उपयोग करें

COALESCE(value [, ...])
The COALESCE function returns the first of its arguments that is not null.  
Null is returned only if all arguments are null. It is often
used to substitute a default value for null values when data is
retrieved for display.

संपादित करें

यहाँ COALESCEआपके प्रश्न के साथ एक उदाहरण दिया गया है :

SELECT AVG( price )
FROM(
      SELECT *, cume_dist() OVER ( ORDER BY price DESC ) FROM web_price_scan
      WHERE listing_Type = 'AARM'
        AND u_kbalikepartnumbers_id = 1000307
        AND ( EXTRACT( DAY FROM ( NOW() - dateEnded ) ) ) * 24 < 48
        AND COALESCE( price, 0 ) > ( SELECT AVG( COALESCE( price, 0 ) )* 0.50
                                     FROM ( SELECT *, cume_dist() OVER ( ORDER BY price DESC )
                                           FROM web_price_scan
                                           WHERE listing_Type='AARM'
                                             AND u_kbalikepartnumbers_id = 1000307
                                             AND ( EXTRACT( DAY FROM ( NOW() - dateEnded ) ) ) * 24 < 48
                                         ) g
                                    WHERE cume_dist < 0.50
                                  )
        AND COALESCE( price, 0 ) < ( SELECT AVG( COALESCE( price, 0 ) ) *2
                                     FROM( SELECT *, cume_dist() OVER ( ORDER BY price desc )
                                           FROM web_price_scan
                                           WHERE listing_Type='AARM'
                                             AND u_kbalikepartnumbers_id = 1000307
                                             AND ( EXTRACT( DAY FROM ( NOW() - dateEnded ) ) ) * 24 < 48
                                         ) d
                                     WHERE cume_dist < 0.50)
     )s
HAVING COUNT(*) > 5

IMHO का COALESCEउपयोग नहीं किया जाना चाहिए AVGक्योंकि यह मूल्य को संशोधित करता है। NULLअज्ञात और कुछ नहीं। यह इसका उपयोग करने जैसा नहीं है SUM। इस उदाहरण में, यदि हम AVGद्वारा प्रतिस्थापित करते हैं SUM, तो परिणाम विकृत नहीं है। एक योग में 0 जोड़ने से किसी को चोट नहीं लगती है लेकिन अज्ञात मानों के लिए औसत के साथ 0 की गणना करने पर आपको वास्तविक औसत नहीं मिलता है।

उस स्थिति में, मैं इन अज्ञात मूल्यों से बचने के लिए खंड price IS NOT NULLमें जोड़ WHEREदूंगा।


1
@ और मैं आपकी क्वेरी का उपयोग करके आपको एक उदाहरण देने की कोशिश कर रहा था। लेकिन मैं हार जाता हूं। मुझे संदेह है कि यह क्वेरी काम करती है। from web_price_scan...बार-बार लगता है ...
ल्यूक एम

सोच रहे लोगों के लिए, NULLIF(v1, v2)इसके विपरीत में बहुत अधिक COALESCEहै NULLअगर यह v1बराबर होता है v2
एस.एम.

24

(यह उत्तर प्रश्न के छोटे और अधिक सामान्य उदाहरण प्रदान करने के लिए जोड़ा गया था - मूल प्रश्न में सभी केस-विशिष्ट विवरणों को शामिल किए बिना)।


यहां दो अलग-अलग "समस्याएं" हैं, पहला यह है कि यदि तालिका या उपश्रेणी में कोई पंक्तियां नहीं हैं, तो दूसरा है यदि क्वेरी में NULL मान हैं।

मेरे द्वारा परीक्षण किए गए सभी संस्करणों के लिए, पोस्टग्रेज और mysql औसत होने पर सभी NULL मानों को अनदेखा कर देंगे, और यह NULL वापस आ जाएगा यदि औसत से अधिक कुछ भी नहीं है। यह आम तौर पर समझ में आता है, क्योंकि NULL को "अज्ञात" माना जाता है। यदि आप इसे ओवरराइड करना चाहते हैं तो आप कोलेसस का उपयोग कर सकते हैं (जैसा कि ल्यूक एम द्वारा सुझाया गया है)।

$ create table foo (bar int);
CREATE TABLE

$ select avg(bar) from foo;
 avg 
-----

(1 row)

$ select coalesce(avg(bar), 0) from foo;
 coalesce 
----------
        0
(1 row)

$ insert into foo values (3);
INSERT 0 1
$ insert into foo values (9);
INSERT 0 1
$ insert into foo values (NULL);
INSERT 0 1
$ select coalesce(avg(bar), 0) from foo;
      coalesce      
--------------------
 6.0000000000000000
(1 row)

बेशक, "फू से" को "से (... यहां कोई भी जटिल तर्क ...) फू के रूप में" से बदला जा सकता है।

अब, तालिका में पूर्ण पंक्ति को 0 के रूप में गिना जाना चाहिए? फिर एवीजी कॉल के अंदर कोलेसस का उपयोग करना पड़ता है।

$ select coalesce(avg(coalesce(bar, 0)), 0) from foo;
      coalesce      
--------------------
 4.0000000000000000
(1 row)

2

मैं इसे प्राप्त करने के 2 तरीके सोच सकता हूं:

  • IFNULL ():

    IFNULL () फ़ंक्शन निर्दिष्ट मान लौटाता है यदि अभिव्यक्ति NULL.If है, तो अभिव्यक्ति NULL नहीं है, यह फ़ंक्शन अभिव्यक्ति लौटाता है।

वाक्य - विन्यास:

IFNULL(expression, alt_value)

IFNULL का उदाहरण () आपकी क्वेरी के साथ:

SELECT AVG( price )
FROM(
      SELECT *, cume_dist() OVER ( ORDER BY price DESC ) FROM web_price_scan
      WHERE listing_Type = 'AARM'
        AND u_kbalikepartnumbers_id = 1000307
        AND ( EXTRACT( DAY FROM ( NOW() - dateEnded ) ) ) * 24 < 48
        AND IFNULL( price, 0 ) > ( SELECT AVG( IFNULL( price, 0 ) )* 0.50
                                     FROM ( SELECT *, cume_dist() OVER ( ORDER BY price DESC )
                                           FROM web_price_scan
                                           WHERE listing_Type='AARM'
                                             AND u_kbalikepartnumbers_id = 1000307
                                             AND ( EXTRACT( DAY FROM ( NOW() - dateEnded ) ) ) * 24 < 48
                                         ) g
                                    WHERE cume_dist < 0.50
                                  )
        AND IFNULL( price, 0 ) < ( SELECT AVG( IFNULL( price, 0 ) ) *2
                                     FROM( SELECT *, cume_dist() OVER ( ORDER BY price desc )
                                           FROM web_price_scan
                                           WHERE listing_Type='AARM'
                                             AND u_kbalikepartnumbers_id = 1000307
                                             AND ( EXTRACT( DAY FROM ( NOW() - dateEnded ) ) ) * 24 < 48
                                         ) d
                                     WHERE cume_dist < 0.50)
     )s
HAVING COUNT(*) > 5
  • COALESCE ()

    COALESCE () फ़ंक्शन किसी सूची में पहला गैर-शून्य मान लौटाता है।

वाक्य - विन्यास:

COALESCE(val1, val2, ...., val_n)

अपनी क्वेरी के साथ COALESCE () का उदाहरण:

SELECT AVG( price )
FROM(
      SELECT *, cume_dist() OVER ( ORDER BY price DESC ) FROM web_price_scan
      WHERE listing_Type = 'AARM'
        AND u_kbalikepartnumbers_id = 1000307
        AND ( EXTRACT( DAY FROM ( NOW() - dateEnded ) ) ) * 24 < 48
        AND COALESCE( price, 0 ) > ( SELECT AVG( COALESCE( price, 0 ) )* 0.50
                                     FROM ( SELECT *, cume_dist() OVER ( ORDER BY price DESC )
                                           FROM web_price_scan
                                           WHERE listing_Type='AARM'
                                             AND u_kbalikepartnumbers_id = 1000307
                                             AND ( EXTRACT( DAY FROM ( NOW() - dateEnded ) ) ) * 24 < 48
                                         ) g
                                    WHERE cume_dist < 0.50
                                  )
        AND COALESCE( price, 0 ) < ( SELECT AVG( COALESCE( price, 0 ) ) *2
                                     FROM( SELECT *, cume_dist() OVER ( ORDER BY price desc )
                                           FROM web_price_scan
                                           WHERE listing_Type='AARM'
                                             AND u_kbalikepartnumbers_id = 1000307
                                             AND ( EXTRACT( DAY FROM ( NOW() - dateEnded ) ) ) * 24 < 48
                                         ) d
                                     WHERE cume_dist < 0.50)
     )s
HAVING COUNT(*) > 5

1
IFNULL () पोस्टग्रेज में एक फ़ंक्शन नहीं है। यह अन्य डेटाबेस में काम कर सकता है लेकिन प्रश्न विशेष रूप से पोस्टग्रेज के बारे में है।
जॉन विल्सन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.