Использование Sum of Group Concat в предложении Have - PullRequest
0 голосов
/ 17 марта 2020

Я хочу найти все идентификаторы, у которых сумма group_concat равна 0. Вот упрощенная таблица из моей.

╔════╦════╦══════════════╦
║ id ║ did║ group_concat ║
╠════╬════╬══════════════╬
║  1 ║  1 ║ 1,1,1        ║
║  2 ║  1 ║ 0            ║
║  3 ║  2 ║ 1,-1         ║
║  4 ║  2 ║ 1,-1,0       ║
║  5 ║  2 ║ 0,0,0        ║
║  6 ║  3 ║ 2,-2         ║
║  7 ║  3 ║ 1,-1,0       ║
║  8 ║  3 ║ 0,0,0        ║
╚════╩════╩══════════════╩

Я хочу получить, когда сумма group_concat равна 0 в тех же делах. Если сумма группового совпадения в любом из дел не равна нулю, ее не должно быть в таблице.

Вот таблица ниже для лучшего понимания.

╔═════╦═════════════════════╦
║ did ║ sum of group_concat ║
╠═════╬═════════════════════╬
║  2  ║ 0                   ║
║  3  ║ 0                   ║
╚═════╩═════════════════════╩

И это оператор запроса, который я пытаюсь использовать.

select sum(val)
from user
group by did
having sum(val) = 0

кажется, что сумма в group_concat недоступна.

Есть ли эффективный способ?

Заранее спасибо

Ответы [ 3 ]

1 голос
/ 17 марта 2020

Просто используйте sum():

select sum(val), group_concat(val)
from user
group by did
having sum(val) = 0

Редактировать:

Вы также хотите условие, такое как:

having sum(val) = 0 and max(val) > 0
0 голосов
/ 17 марта 2020

Одно из решений состоит в том, чтобы аннулировать списки csv с таблицей чисел:

select
    t.did,
    sum(substring_index(substring_index(grp_concat, ',', n.n), ',', - 1)) sum_of_grp_concat
from mytable t
inner join (select 1 n union all select 2 union all select 3 union all select 4 union all select 5) n
    on n.n <= 1 + char_length(grp_concat) - char_length(replace(grp_concat, ',', ''))
group by t.did
having sum_of_grp_concat = 0

Запрос объединяет исходную таблицу с таблицей производных чисел и извлекает каждое отдельное значение с помощью строковых функций; все, что осталось, - это агрегировать и фильтровать с предложением having.

Демонстрация на DB Fiddle :

did | sum_of_grp_concat
--: | ----------------:
  2 |                 0
  3 |                 0

Эта задача было бы намного проще, если бы вы исправили свою схему, чтобы хранить каждое значение CSV в отдельной строке таблицы. Хранение списков csv в столбце базы данных является типичным SQL шаблоном: для этой темы c я бы рекомендовал прочитать этот знаменитый SO-ответ .

0 голосов
/ 17 марта 2020

SUM и все другие функции агрегирования предназначены для расчета по группам строк; не суммировать несколько значений в поле.

Наличие нескольких значений в поле - это анти-паттерн, и, возможно, один из худших, которые вы можете иметь для удобства использования в реляционной базе данных.

Нет простого способа сделать то, что вы хотите в запросе; SQL просто не был предназначен для таких операций. («Эти операции» - это разбор строки целочисленных значений, разделенных запятыми, в список целых чисел.) Для чистого ответа SQL лучшее, на что вы могли бы надеяться, - это хранимая функция, которая принимает строку и использует процедурную логику c чтобы разобрать значения из строки и затем сложить их.)

...