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

Using Sum of Group Concat in Having clause

我想找到 group_concat 之和为 0 的所有 ID。这是我的简化 table。

╔════╦════╦══════════════╦
║ 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        ║
╚════╩════╩══════════════╩

我想在相同的 dos 中 group_concat 的总和为 0 时得到。如果任意一个dos中group concat的总和不为0,则不应该在table.

下面是table以便更好地理解。

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

这是我正在尝试使用的查询语句。

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

似乎 group_concat 中的总和不可用。

有什么有效的方法吗?

提前致谢

只需使用sum():

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

编辑:

您是否也想要这样的条件:

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

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

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

没有简单的方法可以在查询中执行您想要的操作; SQL 并不是为这些类型的操作而设计的。 ("Those operations" 正在将以逗号分隔的整数值字符串解析为整数列表。)对于纯 SQL 答案,您可能希望的最好结果是一个存储函数,它接受一个字符串并使用解析字符串中的值然后对它们求和的过程逻辑。)

一个解决方案涉及使用 table 个数字取消嵌套 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

查询将原始 table 与派生数字 table 连接起来,并使用字符串函数提取每个单独的值;剩下的就是使用 having 子句聚合和过滤。

Demo on DB Fiddle:

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

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