【问题标题】:Is it possible to sql count() only the first instances of a column value?是否可以仅对列值的第一个实例执行 sql count()?
【发布时间】:2017-08-26 23:45:36
【问题描述】:

我想计算每个用户初始公司订阅的数量。

在下面的数据集中,我希望 user1 的计数为 3,而 user2 的计数为 0。因为 user2 订阅的两家公司之前都被 user1 订阅过。

id    user    companyId    activity 
-----------------------------------   

1     1       101          subscribe
2     1       101          unsubscribe
3     1       102          subscribe
4     1       103          subscribe

5     2       102          unsubscribe
6     2       102          subscribe
7     2       103          unsubscribe
8     2       103          subscribe

这在 SQL 中是否可行,如果可以,我将如何处理?

欢迎对问题措辞进行任何改进,因为我一直在努力解释清楚。

【问题讨论】:

  • id代表时间顺序吗?
  • 是的。 id 越低,创建的越早。
  • 假设id 列是IDENTITY 列,我不会依赖它代表插入时间。虽然不寻常,但在某些情况下,id 可能会被乱序分配。最好有一个日期时间字段...
  • 你好。同意。在这种情况下,这是有保证的,但如果需要,很容易将 id 字段换成日期时间。

标签: sql sql-server count


【解决方案1】:

你可以使用窗口函数row_number():

select  [user],
        count(case when activity = 'subscribe' and rn = 1 then 1 end)
from   (select [user],
               activity,
               row_number() over (partition by companyId order by id) rn
        from   mytable) as base
group by [user]

看到它在rextester.com上运行

【讨论】:

  • 我永远也想不出这个!谢谢你。也为了测试它的链接。这是一流的答案,非常感谢。
【解决方案2】:

您可以使用子查询(下面的fs)获取与每个公司的第一个订阅相关联的id,然后为该子集计算每个用户的公司数,如下所示:

select
    user,
    count(*) as initial_subscriptions
from
    (
        select companyId, min(id) as id
        from the_table
        where activity = 'subscribe'
        group by companyId
    ) as fs
    inner join the_table on the_table.id = fs.id
group by
    user;

【讨论】:

  • 我认为这不会在示例中为 user2 输出一行。此外,您还需要为内部查询中的第二列添加别名:min(id) as id
  • 非常感谢。我选择了另一个答案,因为那是我最终使用的答案,但我投了这个答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-08
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-17
  • 2017-12-23
相关资源
最近更新 更多