postgresql döndürülen değer null ise 0 döndürür


106

Avg (fiyat) döndüren bir sorgum var

  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

hiçbir değer yoksa nasıl 0 döndürür?


1
Sorgunuzun iyi biçimlendirildiğinden emin misiniz?
Luc M

2
@LucM: İyi biçimlendirilmiş bir sorgu olamaz. (Madde, bir "tarafından grubu" olmadan madde "olan".)
Mike Sherrill 'kedi anımsama'

her şey yolunda gider, ancak bazen kurallar karşılanmadığında hiçbir şey döndürmez. Ek olarak, ortalama olarak nasıl gruplaşabilirim, bunun mümkün olduğunu düşünmüyorum || ne anlamı var? Çoklu seçim from web_price_scan, ayrı seçimlerdir; buradaki sorunun ne olduğundan emin değil misiniz?
Andrew

A havingolmadan bir cümle kullanmak uygundur group by(tek bir grup için öntanımlıdır). whereToplam sonuçlara ilişkin bir madde görevi görür . Bu durumda, satırlar yalnızca 1. düzey alt sorgu tarafından 5'ten fazla satır döndürülürse döndürülür.
bruceskyaus

Yanıtlar:


186

Kullanım kaynaşabilecek

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.

Düzenle

İşte COALESCEsorgunuzla ilgili bir örnek :

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

Değeri değiştirdiği için IMHO COALESCEile birlikte kullanılmamalıdır AVG. NULLbilinmeyen ve başka hiçbir şey anlamına gelmez. İçinde kullanmak gibi değil SUM. Biz değiştirirseniz Bu örnekte, AVGtarafından SUM, sonuç bozuk değildir. Bir toplama 0 eklemek kimseye zarar vermez ancak bilinmeyen değerler için 0 ile bir ortalama hesaplarsanız, gerçek ortalamayı elde edemezsiniz.

Bu durumda, ben eklersiniz price IS NOT NULLiçinde WHEREbu bilinmeyen değerlerini önlemek için fıkra.


1
@Andrew Sorgunuzu kullanarak size bir örnek vermeye çalışıyordum. Ama kayboldum. Bu sorgunun işe yaradığından şüpheliyim. from web_price_scan...tekrarlanıyor gibi görünüyor ...
Luc M

Merak edenler için, NULLIF(v1, v2)hemen hemen tersini yapar COALESCEDöndürdüğü ki NULLeğer v1eşittir v2.
sm

25

(bu cevap, soruya daha kısa ve daha genel örnekler sağlamak için eklenmiştir - orijinal soruya tüm vakaya özgü ayrıntılar dahil edilmemiştir).


Burada iki farklı "sorun" vardır, birincisi, bir tablo veya alt sorguda satır yoksa, ikincisi sorguda NULL değerler olup olmadığıdır.

Test ettiğim tüm sürümler için postgres ve mysql, ortalama alırken tüm NULL değerlerini göz ardı edecek ve ortalanacak hiçbir şey yoksa NULL döndürecektir. Bu genellikle anlamlıdır, çünkü NULL "bilinmeyen" olarak kabul edilir. Bunu geçersiz kılmak istiyorsanız, birleştirme kullanabilirsiniz (Luc M'nin önerdiği gibi).

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

tabii ki, "foo'dan", "from (... burada herhangi bir karmaşık mantık ...) ile foo" ile değiştirilebilir.

Şimdi, tablodaki NULL satırı 0 olarak sayılmalı mı? Daha sonra birleştirme avg çağrısının içinde kullanılmalıdır.

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

3

Bunu başarmanın 2 yolunu düşünebilirim:

  • IFNULL ():

    IFNULL () işlevi, ifade NULL ise belirtilen bir değeri döndürür. İfade NOT NULL ise, bu işlev ifadeyi döndürür.

Sözdizimi:

IFNULL(expression, alt_value)

Sorgunuzla birlikte IFNULL () örneği:

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
  • KÖMÜR ()

    COALESCE () işlevi, bir listedeki ilk boş olmayan değeri döndürür.

Sözdizimi:

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

Sorgunuzla birlikte COALESCE () örneği:

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

2
IFNULL (), Postgres'te bir işlev değildir. Bu başka veritabanlarında da işe yarayabilir, ancak soru özellikle Postgres ile ilgilidir.
Jon Wilson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.