【问题标题】:Incrementing Count within a Group By增加组内计数
【发布时间】:2017-11-04 08:40:11
【问题描述】:

我正在尝试在一组结果中获取递增计数器。

例如,假设我有一个messages 表:

messages
--------
- id (int)
- user_id (int)
- sent_at (date)
- body (text)

我想执行一个查询,结果如下:

+---------+------------+-------------+---------+
| user_id | message_id | sent_at     | counter |
+---------+------------+-------------+---------+
|       1 |          1 |  2017-01-01 |       1 |
|       1 |          3 |  2017-01-15 |       2 |
|       1 |          4 |  2017-01-22 |       3 |
|       2 |          2 |  2017-01-06 |       1 |
|       2 |          6 |  2017-01-22 |       2 |
|       3 |          5 |  2017-01-22 |       1 |
|       3 |          7 |  2017-01-28 |       2 |
|       3 |          8 |  2017-02-03 |       3 |
|       3 |          9 |  2017-02-14 |       4 |
+---------+------------+-------------+---------+

基本上,计数器只在user_id 组内递增,每个内部组按sent_at 列排序。

我知道我可以使用以下 SQL 轻松获取前三列:

SELECT
   user_id,
   id AS message_id,
   sent_at
FROM messages
ORDER BY
    user_id,
    sent_at

但我需要第四个count 专栏。

我知道我可以使用ROW_NUMBER() 来获取结果行号:

SELECT
   user_id,
   id AS message_id,
   sent_at,
   ROW_NUMBER() OVER(ORDER BY user_id, sent_at) AS counter
FROM messages
ORDER BY
    user_id,
    sent_at

但这给了我以下结果:

+---------+------------+-------------+---------+
| user_id | message_id | sent_at     | counter |
+---------+------------+-------------+---------+
|       1 |          1 |  2017-01-01 |       1 |
|       1 |          3 |  2017-01-15 |       2 |
|       1 |          4 |  2017-01-22 |       3 |
|       2 |          2 |  2017-01-06 |       4 |
|       2 |          6 |  2017-01-22 |       5 |
|       3 |          5 |  2017-01-22 |       6 |
|       3 |          7 |  2017-01-28 |       7 |
|       3 |          8 |  2017-02-03 |       8 |
|       3 |          9 |  2017-02-14 |       9 |
+---------+------------+-------------+---------+

如果我可以在每个新的user_id 之后以某种方式重置计数器,我就会得到我正在寻找的结果。

【问题讨论】:

    标签: sql sql-server select count sql-server-2014


    【解决方案1】:

    您只需使用PARTITION BY:

    SELECT
       user_id,
       id AS message_id,
       sent_at,
       ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY user_id, sent_at) AS counter
    FROM messages
    ORDER BY
        user_id,
        sent_at;
    

    【讨论】:

      【解决方案2】:

      使用row_number 是正确的方法。您只是缺少一个 partition by 子句来为每个不同的 user_id 获取一个新计数器:

      SELECT
         user_id,
         id AS message_id,
         sent_at,
         ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY sent_at) AS counter
         -- Here ----------^
      FROM messages
      ORDER BY
          user_id,
          sent_at
      

      【讨论】:

        【解决方案3】:

        您正在寻找partition by:

        SELECT user_id, id AS message_id, sent_at,
               row_number() over (partition by user_id order by sent_at) AS counter
        FROM messages m
        ORDER BY user_id, sent_at;
        

        【讨论】:

          猜你喜欢
          • 2018-04-24
          • 2021-12-18
          • 2010-12-21
          • 1970-01-01
          • 2017-06-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多