增加组内的计数

Tyl*_*eed 3 sql sql-server select count sql-server-2014

我试图在一组结果中得到一个递增计数器.

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

messages
--------
- id (int)
- user_id (int)
- sent_at (date)
- body (text)
Run Code Online (Sandbox Code Playgroud)

我想执行一个查询,给我这样的结果:

+---------+------------+-------------+---------+
| 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 |
+---------+------------+-------------+---------+
Run Code Online (Sandbox Code Playgroud)

实质上,计数器仅在user_id组内递增,每个内部组按sent_at列排序.

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

SELECT
   user_id,
   id AS message_id,
   sent_at
FROM messages
ORDER BY
    user_id,
    sent_at
Run Code Online (Sandbox Code Playgroud)

但我需要第四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
Run Code Online (Sandbox Code Playgroud)

但这给了我以下结果:

+---------+------------+-------------+---------+
| 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 |
+---------+------------+-------------+---------+
Run Code Online (Sandbox Code Playgroud)

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

Lam*_*mak 5

你需要简单地使用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;
Run Code Online (Sandbox Code Playgroud)


Mur*_*nik 5

使用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
Run Code Online (Sandbox Code Playgroud)


Gor*_*off 5

您正在寻找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;
Run Code Online (Sandbox Code Playgroud)