在Haveing子句中使用Group Concat的总和

时间:2020-03-16 22:21:47

标签: mysql sql csv group-by having-clause

我想找到group_concat总和为0的所有id。这是我的简化表。

╔════╦════╦══════════════╦
║ 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时,我想获取。如果在任何一个集中的concat组的总和不等于零,则不应在表中。

为便于更好地理解,请参见下表。

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

这是我要使用的查询语句。

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

似乎group_concat中的总和不可用。

有什么有效的方法吗?

先谢谢您

3 个答案:

答案 0 :(得分:1)

只需使用sum()

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

编辑:

您是否还需要以下条件:

having sum(val) = 0 and max(val) > 0

答案 1 :(得分:0)

SUM和所有其他聚合函数用于跨行组进行计算;不对字段中的多个值求和。

在一个字段中具有多个值是一种反模式,并且可能是关系数据库中可用性最差的一种。

没有简单的方法可以在查询中执行所需的操作; SQL并不是专门为这类操作而设计的。 (“那些操作”是将用逗号分隔的整数值字符串解析为整数列表。)对于纯SQL答案,最好的解决方案是使用字符串并使用过程逻辑来解析整数的存储函数。值从字符串中取出然后求和。)

答案 2 :(得分:0)

一种解决方案涉及用数字表将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子句进行过滤。

Demo on DB Fiddle

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

如果要修复模式以便将每个csv值存储在单独的表行中,则此任务将更容易实现。在数据库列中存储csv列表是典型的SQL反模式:在这个主题上,我建议阅读this famous SO answer