2017-06-02 68 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;