Если случаи поломки при использовании накопительного

Я пытаюсь, чтобы столбец имел определенное значение в строке свертки, но когда я добавляю "если", все остальные строки получают последнее значение в этом столбце.

Зачем? И как правильно это решить?

Скрипка: http://rextester.com/TTYI19512

Пример:

CREATE TABLE ru (ru_id INT KEY, name VARCHAR(20));
INSERT INTO ru VALUES (1, 'A'),(2, 'B');

CREATE TABLE rud (rud_id INT KEY, ru_id INT, value INT);
INSERT INTO rud VALUES (1, 1, 3), (2, 1, 5), (3, 2, 4), (4, 2, 9);

SELECT
   ru_id,
   IF(ru_id IS NULL, 'Total', name) as name,
   COUNT(rud.value),
   SUM(rud.value)
FROM ru
   INNER JOIN rud USING (ru_id)
GROUP BY ru_id WITH ROLLUP;

Текущий результат:

+-------+-------+------------------+----------------+
| ru_id | name  | COUNT(rud.value) | SUM(rud.value) |
+-------+-------+------------------+----------------+
|     1 | B     |                2 |              8 |
|     2 | B     |                2 |             13 |
|  NULL | Total |                4 |             21 |
+-------+-------+------------------+----------------+

Ожидаемый результат:

+-------+-------+------------------+----------------+
| ru_id | name  | COUNT(rud.value) | SUM(rud.value) |
+-------+-------+------------------+----------------+
|     1 | A     |                2 |              8 |
|     2 | B     |                2 |             13 |
|  NULL | Total |                4 |             21 |
+-------+-------+------------------+----------------+

2 ответа

Только чистые функции и столбцы, включенные в group-by, разрешены в чистом sql, поэтому, поместив функцию-агрегацию вокруг столбца name, он сделает это разрешенным запросом и даст ожидаемый результат.

SELECT
   ru_id,
   IF(ru_id IS NULL, 'Total', MAX(name)) as name,
   COUNT(rud.value),
   SUM(rud.value)
FROM ru
   INNER JOIN rud USING (ru_id)
GROUP BY ru_id WITH ROLLUP;

Спасибо @ThorstenKettner & @CBroe за вклад в поле для комментариев.

Оберните условие if агрегатной функцией, такой как MAX (это не имеет значения, поскольку это строка, также может быть MIN)

SELECT IFNULL(ru_id,'Total'), MAX(IF(ru_id IS NULL, 'Total', name)) as name,
 COUNT(rud.value), SUM(rud.value) 
FROM ru INNER JOIN rud USING (ru_id) 
GROUP BY ru_id WITH ROLLUP;

Вы можете сделать итоговое значение для идентификатора, но не для имени, в последней строке имя будет случайным. Также ваш текущий результат не отображает итоговое значение.

Другие вопросы по тегам