关于分组 2 列的 SQL 选择查询

Posted

技术标签:

【中文标题】关于分组 2 列的 SQL 选择查询【英文标题】:SQL select query about grouping 2 columns 【发布时间】:2012-06-30 01:15:52 【问题描述】:

我正在努力解决这个问题 - 看起来很简单

下表记录了哪个用户观看了哪个视频

topic_user_id |主题ID |用户身份 1 | 10 | 3 2 | 10 | 4 3 | 11 | 5 4 | 11 | 3 5 | 12 | 6 6 | 13 | 6 7 | 14 | 7 8 | 11 | 8 9 | 11 | 9 10 | 14 | 10 11 | 15 | 11 12 | 16 | 11 13 | 17 | 11

现在要了解有多少用户观看了特定视频 - 我有以下查询。

有多少用户观看了特定视频

从 topic_user 中选择 count(distinct(user_id)) 作为“用户数”,topic_id 其中 user_id 不为空 按 topic_id 分组

输出

用户数量 | topic_id 2 | 10 4 | 11 1 | 12 1 | 13 2 | 14 1 | 15 1 | 16 1 | 17 读作:2 位用户观看了主题 10 ,4 位用户观看了主题 11 等等

这很好用 - 但我正在寻找的是找到:

有多少用户观看了 1 个视频 有多少用户观看了 2 个视频 有多少用户观看了 3 个视频

输出应该是这样的

用户数量 |观看的视频数 6 | 1 2 | 2 1 | 3 阅读为 - 6 人仅观看了 1 个视频,2 人观看了 2 个视频,依此类推。

需要一些帮助。

提前致谢

【问题讨论】:

【参考方案1】:

可能有更简单的方法,但子查询可以工作

select
    videos as 'Number of videos',
    count(user_id) as 'Num of Users'
from (
   select
        count(distinct(topic_id)) as videos,
        user_id from topic_user
   group by
        user_id
 ) sub
 group by
    videos

【讨论】:

如果您想知道有多少用户观看了 n 个视频,不确定这是否有用【参考方案2】:
select u.n as `Number of Video watched`, count(t.user_id)
from
    (select user_id, count(*) as `cnt`
    from topic_user 
    group by user_id) t INNER JOIN(
        SELECT 1 as `n` FROM DUAL 
        UNION 
        SELECT 2 as `n` FROM DUAL 
        UNION
        SELECT 3 as `n` FROM DUAL) u ON u.n = t.cnt
group by u.n

小提琴:http://sqlfiddle.com/#!2/844ee/15

【讨论】:

谢谢 - 但这需要我为每个视频计数添加一个 SELECT UNION - 我的意思是如果最大视频计数为 10 - 我需要在内部连接中有 10 个 SELECT UNION 子句。我说的对吗? 不,如果你想显示有多少用户观看了 10 个视频,而不是那些观看了 0->9 个视频的用户,那么你只需要一个 SELECT 10 as n FROM dual【参考方案3】:

试试这个::

Select first_table.count(distinct(user_id))  as 'Number of Users', SUM(Count(topic_id))
from
(select count(distinct(user_id)) as 'Number of Users',topic_id from topic_user
where user_id is not null
group by topic_id) as first_table group by Count(topic_id)

【讨论】:

谢谢 - 我收到一个错误 - 不能在用于按列表分组的表达式中使用聚合或子查询 - sqlfiddle.com/#!3/af27e/5【参考方案4】:

试试这个

SELECT videos AS `Number of videos`,COUNT(user_id) AS `Num of Users`
FROM (SELECT COUNT(DISTINCT(topic_id)) AS videos,user_id FROM topic_user
GROUP BY user_id) sub_query
GROUP BY
videos

【讨论】:

谢谢,但我无法让它在 sqlfiddle sqlfiddle.com/#!3/af27e/6 上运行【参考方案5】:

“有多少用户观看了 n 个视频”可以解释为两种方式:

1) 无论标题如何,有多少用户观看了 n 个视频?同一个视频标题可能被观看了两次。

select videoCount, count(*) as userCount
  from (
    select count(*) as videoCount
      from topic_user
    group by user_id
  ) t
 group by videoCount

2) 有多少用户观看了 n 个不同的视频标题。

select videoCount, count(*) as userCount
  from (
    select count(distinct topic_id) as videoCount
      from topic_user
    group by user_id
  ) t
 group by videoCount

【讨论】:

感谢您指出这一点-我正在寻找观看过特定视频一次的不同用户的数量-我在 sqlfiddle 上尝试了您的两个查询,但没有产生预期的结果-sqlfiddle.com/#!3/af27e/9 @Gublooo - 哎呀 - 当然我的原始代码给出了错误的答案。这是一个愚蠢的错误 - 感谢您让我知道 :) 我已经修复了代码以在两种情况下都给出正确的答案。使用您的测试数据,两个查询都会给出相同的结果。

以上是关于关于分组 2 列的 SQL 选择查询的主要内容,如果未能解决你的问题,请参考以下文章

数据库查询选择所有列,包括按“分组依据”的每条记录的计数

如何使用正则表达式选择分组

新列的 SQL 不同分组依据

SQL Server 有一个选择查询作为一个选择列的一部分

SQL 查询中分组 COUNT 的总和

SQL - 选择按多个字段分组的前 n 个,按计数排序