Разница между GROUP BY B, A и GROUP BY COALESCE (B, A)

20

Я очень запутался.

Может ли кто-нибудь любезно объяснить, при каких обстоятельствах я хотел бы использовать GROUP BY COALESCE?

Я предполагаю, что я использовал бы это, если бы я хотел условно сгруппировать набор данных по столбцу B (если B не был нулевым) и по столбцу A в противном случае. Это звучит правильно?

Марк Макларен
источник

Ответы:

37

С GROUP BY b,aкортежами (null, 1), (1,1), (2,1)и (17,1)будет в конечном итоге в четырех различных группах.

С GROUP BY coalesce(b,a)кортежами (null,1), (1,1), (2,1)и (17,1)будет в конечном итоге в той же группе.

Если вы хотите «условную» группировку, то да, версия с coalesce, вероятно, то, что вы хотите.

a_horse_with_no_name
источник
Крис Дата : «Тип», который содержит нуль, не является типом (потому что типы содержат значения). «Кортеж», который содержит нуль, не является кортежем (потому что кортежи содержат значения). »
onedaywhen
@onedaywhen: хорошо, в этом разница между теорией и практикой;)
a_horse_with_no_name
Моя точка зрения: в этом разница между кортежем в отношении и строкой в ​​выражении таблицы SQL. Кортеж не применяется к SQL, как в теории, так и на практике.
onedaywhen
@onedaywhen: так ты имеешь в виду, что я должен изменить свою формулировку? Какое слово вы бы порекомендовали для выражения комбинации двух (столбцов) значений в SQL? Они не обязательно должны быть из одной и той же таблицы и не быть полной строкой.
a_horse_with_no_name
1
Например, в учебном пособии D TUPLE { a 17 , b 1 }то же самое, что TUPLE { b 1 , a 17 }и в SQL, но конструктор значения строки (17, 1)не совпадает с конструктором значения строки (1, 17). Вот почему ваши «пары» не являются кортежами. Поскольку вы пропустили конструктор типа строки, я должен исходить из контекста, которым они являются, (a, b)а не (b, a)его включение все равно не сделает его кортежем. Напротив, TUPLE { 17 , 1 }это не является допустимым вызовом кортежа в Tutorial D, и не является TUPLE { a null , b 1 }.
onedaywhen
16

Вот демонстрация отличного +1 ответа a_horse_with_no_name .

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
Ли Риффель
источник
2
Хорошая демонстрация!
a_horse_with_no_name
Я должен получить рефлекс, чтобы думать о «уровне», это очень полезно!
Люк М