2017-06-02 63 views
3

我想在一组结果中获得递增计数器。组内递增计数通过

例如,假设我有一个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,我会得到我正在寻找的结果。

回答

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; 
+0

完美,谢谢! –

4

使用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 
4

您正在寻找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;