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,我会得到我正在寻找的结果.
你需要简单地使用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)
使用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)
您正在寻找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)
| 归档时间: |
|
| 查看次数: |
155 次 |
| 最近记录: |