【问题标题】:Can I count multiple columns with Group By?我可以使用 Group By 计算多列吗?
【发布时间】:2019-06-17 12:31:47
【问题描述】:

我有一个包含这些列的表格:

s, s2, s3  
1, 2,  3  
4  
1, 3  
4, 2,  
2, 1  
3, 4  
4  

我想知道 s 列中的唯一值在 s、s2 和 s3 列中出现的次数。

到目前为止,我有:

$query = "SELECT s, COUNT(*) as count FROM table GROUP BY s";

这会给我:

1 - count 2  
2 - count 1  
3 - count 1  
4 - count 3  

但我也想计算 s2 和 s3 列,所以结果是:

1 - count 3  
2 - count 3  
3 - count 3  
4 - count 4

知道我必须如何编辑查询,以便可以按列 s 的值计算列 s、s2 和 s3 组吗?

亲切的问候,

阿里

【问题讨论】:

  • 你可能想用 M:N 关系重新设计 youe 表并使用JOINs

标签: mysql group-by count


【解决方案1】:

所有列都需要一个 UNION ALL,然后计算它们:

select
  t.s, count(*) counter
from (
  select s from tablename union all
  select s2 from tablename union all
  select s3 from tablename
) t
where t.s is not null
group by t.s

请参阅demo
结果:

| s   | counter |
| --- | ------- |
| 1   | 3       |
| 2   | 3       |
| 3   | 3       |
| 4   | 4       |

如果在s2s3 列中存在s 列中不存在的值,并且您希望将它们排除在外,则不要:

where t.s is not null

使用

where t.s in (select s from tablename)

【讨论】:

  • 我第一次使用 Union,我必须说,它看起来很简单...... ;-)
  • 这很简单,但对于非常大的数据集效率不高。
  • 另一个简单的问题,在我的帖子中,我遗漏了一些 Where 子句,因为我认为它们会很容易插入,但我无法完成工作。还有 2 个其他列,即 season 和 round,我想添加 WHERE season = '2018/2019' AND round = 34 但我收到一个错误,即列季节不正确。有什么想法吗?
  • 您必须在 select 语句中指定它们才能在 where 子句中使用它们。
  • 我在db-fiddle.com/f/4C1FxXFnt97HkTWhfRXHNx/5 中尝试过,但仍然收到错误“字段列表中的未知列 'tablename.season'”
【解决方案2】:

@forpas 的回答很好。但是,您应该考虑两件事。

  1. 由于使用union,查询会随着数据大小的增加而变慢。
  2. 如果输入如下:
s, s2, s3  
1, 2,  3  
4  
1, 3  
4, 2,  
2, 1  
3, 4  
4     5

提供的查询的结果将是:

| s   | counter |
| --- | ------- |
| 1   | 3       |
| 2   | 3       |
| 3   | 3       |
| 4   | 4       |
| 5   | 1       |

而它应该保持不变,因为 s 列中不存在 5。

为了解决以上两个问题,我提出了使用JOIN而不是UNION的方法:

SELECT t3.s, IF(t3.s = t4.s3, cnt1 + 2, cnt1 + 1) as counter FROM 
    (SELECT *, count(*) AS cnt1 FROM 
        (SELECT s from table) AS t1 
        LEFT JOIN 
        (SELECT s2 FROM table) AS t2 
        ON t1.s = t2.s2 GROUP BY t1.s
    ) AS t3 
    LEFT JOIN 
    (SELECT s3 FROM table) AS t4 
    ON t3.s = t4.s3 
ORDER BY t3.s

查询可能看起来有点冗长和复杂,但仔细研究一下它的逻辑真的很简单。

第 1 步
我在这里所做的是从 s 列到 s2 进行左连接并为此计算结果,这样它会给你的数字比总共存在的数字少 1 个,因为它会使关系从左到右。

第 2 步
然后我从 s 到 s3 进行了左连接,如果找到关系,则仅将步骤 1 的计数增加 1。

第 3 步
最终我将计数增加了 1,以便我们可以将关系数转换为实体数。

我希望它有意义

【讨论】:

  • @forpas 在问题中,OP 说:“我想知道 s 列中的唯一值出现在 s、s2 和 s3 列中的次数”,这强调了我们只对s 列的值,因此如果某些值出现在 s2 和 s3 列中,而这些值在 s 列中不存在,则应简单地忽略
  • @Arie 我的回答解决了您的问题吗?如果是,那么请将其标记为已接受以在 stackoverflow 上关闭此线程。谢谢!
  • 为什么投反对票?每当您投反对票时,请始终删除评论
  • 我不记得我投了反对票,我不想那样做 ;-)
  • @Arie 请注意我在使用您接受的答案时提到的问题。如果它不打扰您的需求,那么一切都很好。只是想让你意识到这一点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-07
  • 2011-03-11
  • 2012-09-23
  • 2011-07-22
  • 2020-08-10
相关资源
最近更新 更多