Różnica między GROUP BY B, A i GROUP BY COALESCE (B, A)

20

Byłem bardzo zdezorientowany.

Czy ktoś mógłby uprzejmie wyjaśnić, w jakich okolicznościach chciałbym skorzystać z GROUP BY COALESCE?

Domyślam się, że użyłbym tego, gdybym chciał warunkowo pogrupować zestaw danych według kolumny B (jeśli B nie był równy null) i według kolumny A inaczej. Czy to brzmi dobrze?

Mark McLaren
źródło

Odpowiedzi:

37

Z GROUP BY b,akrotek (null, 1), (1,1), (2,1)a (17,1)zakończy się w czterech różnych grup.

Z GROUP BY coalesce(b,a)krotek (null,1), (1,1), (2,1)a (17,1)zakończy się w tej samej grupie.

Jeśli chcesz grupowanie „warunkowe”, to tak, coalesceprawdopodobnie wersja z jest prawdopodobnie tym, czego chcesz.

koń bez imienia
źródło
Chris Date : „Typ„ zawierający null ”nie jest typem (ponieważ typy zawierają wartości).„ Krotka ”zawierająca null nie jest krotką (ponieważ krotki zawierają wartości).”
poniedziałek
@onedaywhen: cóż, taka jest różnica między teorią a praktyką;)
a_horse_w_na_name
Moja uwaga: to różnica między krotką w relacji a wierszem w wyrażeniu tabeli SQL. Krotka nie dotyczy SQL, zarówno w teorii, jak i w praktyce.
poniedziałek
@onedaywhen: więc masz na myśli, że powinienem zmienić sformułowanie? Które słowo poleciłbyś wtedy do wyrażenia kombinacji dwóch (kolumnowych) wartości w SQL? Nie muszą koniecznie pochodzić z tej samej tabeli ani być kompletnym wierszem.
a_horse_w_no_name
1
Na przykład w samouczku D TUPLE { a 17 , b 1 }jest taki sam TUPLE { b 1 , a 17 }, ale w SQL konstruktor wartości wiersza (17, 1)nie jest taki sam jak konstruktor wartości wiersza (1, 17). Dlatego twoje „pary” nie są krotkami. Ponieważ pominąłeś konstruktor typu wiersza, muszę raczej założyć z kontekstu, że są (a, b), niż, (b, a)ale jego włączenie nadal nie sprawi, że będzie to krotka. W przeciwieństwie do tego, TUPLE { 17 , 1 }nie jest poprawnym wywołaniem krotki w samouczku D, ani nie jest TUPLE { a null , b 1 }.
poniedziałek
16

Oto demonstracja doskonałej odpowiedzi +1 konia .

SQL> WITH Data AS (
  2     SELECT level, DECODE(Level,3,NULL,1) A
  3        , DECODE(level,2,NULL,4,2,1) B
  4     FROM dual connect by level <=5
  5     )
  6  SELECT A, B, count(*) FROM Data GROUP BY B, A;

A B   COUNT(*)
- - ----------
1 1          2
1            1
1 2          1
  1          1


SQL> WITH Data AS (
  2     SELECT level, DECODE(Level,3,NULL,1) A
  3        , DECODE(level,2,NULL,4,2,1) B
  4     FROM dual connect by level <=5
  5     )
  6  SELECT COALESCE(B, A) X, count(*) FROM Data GROUP BY COALESCE(B, A);

X   COUNT(*)
- ----------
1          4
2          1
Leigh Riffel
źródło
2
Niezła demonstracja!
a_horse_w_na_name
Muszę odruchowo pomyśleć o „poziomie”, to bardzo przydatne!
Luc M