Postgresql

在 PostgreSQL 中重置的行號

  • September 14, 2016

我在 PostgreSQL 中有這個數據集:

使用者ID | 日期 | is_cleared |
---------------+-------------------------+------------+
C | 2016-08-03 18:28:38.37 | 1 |
一個 | 2016-08-01 19:59:36.548 | 0 |
一個 | 2016-08-01 23:38:29.912 | 0 |
一個 | 2016-08-04 19:03:30.585 | 0 |
一個 | 2016-08-08 19:53:20.251 | 0 |
一個 | 2016-08-11 21:00:16.075 | 0 |
一個 | 2016-08-13 21:07:01.336 | 0 |
一個 | 2016-08-15 10:17:32.746 | 0 |
一個 | 2016-08-17 11:54:16.75 | 0 |
一個 | 2016-08-18 21:12:22.717 | 0 |
一個 | 2016-08-21 19:59:26.441 | 0 |
一個 | 2016-08-22 17:19:42.215 | 0 |
一個 | 2016-08-24 20:18:45.516 | 1 |
一個 | 2016-08-27 13:22:33.98 | 1 |
一個 | 2016-08-31 16:09:25.756 | 0 |
乙| 2016-08-03 21:10:32.945 | 1 |
乙| 2016-08-05 20:40:55.644 | 1 |
乙| 2016-08-06 10:59:00.796 | 1 |
乙| 2016-08-09 22:36:50.674 | 0 |
乙| 2016-08-11 09:37:21.29 | 1 |
乙| 2016-08-13 10:15:15.858 | 1 |
乙| 2016-08-26 09:56:48.937 | 1 |
乙| 2016-08-29 09:34:13.96 | 1 |

我需要這樣的輸出:

使用者ID | 日期 | is_cleared | 自定義排名 
---------------+-------------------------+------------+---------
C | 2016-08-03 18:28:38.37 | 1 | 1
一個 | 2016-08-01 19:59:36.548 | 0 | 1
一個 | 2016-08-01 23:38:29.912 | 0 | 2
一個 | 2016-08-04 19:03:30.585 | 0 | 3
一個 | 2016-08-08 19:53:20.251 | 0 | 4
一個 | 2016-08-11 21:00:16.075 | 0 | 5
一個 | 2016-08-13 21:07:01.336 | 0 | 6
一個 | 2016-08-15 10:17:32.746 | 0 | 7
一個 | 2016-08-17 11:54:16.75 | 0 | 8
一個 | 2016-08-18 21:12:22.717 | 0 | 9
一個 | 2016-08-21 19:59:26.441 | 0 | 10
一個 | 2016-08-22 17:19:42.215 | 0 | 11
一個 | 2016-08-24 20:18:45.516 | 1 | 12
一個 | 2016-08-27 13:22:33.98 | 1 | 1
一個 | 2016-08-31 16:09:25.756 | 0 | 1
乙| 2016-08-03 21:10:32.945 | 1 | 1
乙| 2016-08-05 20:40:55.644 | 1 | 1
乙| 2016-08-06 10:59:00.796 | 1 | 1
乙| 2016-08-09 22:36:50.674 | 0 | 1
乙| 2016-08-11 09:37:21.29 | 1 | 2
乙| 2016-08-13 10:15:15.858 | 1 | 1
乙| 2016-08-26 09:56:48.937 | 1 | 1
乙| 2016-08-29 09:34:13.96 | 1 | 1

**is_cleared**基本上我的目標是計算零的數量,包括標誌中零後第一次出現的“1” 。

數據按 排序,date也應按 分區user_id

視窗函式和單個子查詢:

SELECT user_id, date, is_cleared
    , count(*) OVER (PARTITION BY user_id, grp ORDER BY date) AS custom_rank
FROM  (
  SELECT user_id, date, is_cleared
       , count(is_cleared = 1 OR NULL) OVER (PARTITION BY user_id ORDER BY date **DESC**) AS grp
  FROM   tbl
  ) t
ORDER  BY user_id, date;

這裡的特殊困難:每個分區都. 1在大多數類似的情況下,每個分區都. 1簡單的解決方案是1按降序計算出現的次數。這樣,每個分區都包含下一個分區(1如果存在)。瞧。

假設所有涉及的列都是唯一的NOT NULL(user_id, date)

基本:

旁白:

  • 第一行B得到custom_rank = 1。不是2
  • 該列is_cleared確實應該是boolean.
  • timestamp不應將列稱為“日期” 。

引用自:https://dba.stackexchange.com/questions/149519