簡體   English   中英

如何編寫查詢以將行號(1到n)附加到每個組的每個記錄

[英]How to write a query to attach rownumber(1 to n) to each records for each group

我有一個像下面的數據集

|date|flag|
|20190503|0|
|20190504|1|
|20190505|1|
|20190506|1|
|20190507|1|
|20190508|0|
|20190509|0|
|20190510|0|
|20190511|1|
|20190512|1|
|20190513|0|
|20190514|0|
|20190515|1|

我要實現的是將連續的日期按flag = 1進行分組,並在flag = 1的連續幾天的第一天為標記1添加一個列計數器,對於第二天的第2天添加2列,等等,為flag分配0 = 0

|date|flag|counter|
|20190503|0|0|
|20190504|1|1|
|20190505|1|2|
|20190506|1|3|
|20190507|1|4|
|20190508|0|0|
|20190509|0|0|
|20190510|0|0|
|20190511|1|1|
|20190512|1|2|
|20190513|0|0|
|20190514|0|0|
|20190515|1|1|

我嘗試了解析函數和層次結構查詢,但是仍然沒有找到解決方案,尋求幫助,任何提示都值得贊賞!

謝謝你洪

您可以使用零的累加和定義組。 然后使用row_number()

select t.*,
       (case when flag = 0 then 0
             else row_number() over (partition by grp order by date)
        end) as counter
from (select t.*,
             sum(case when flag = 0 then 1 else 0 end) over (order by date) as grp
      from t
     ) t;

一種非常不同的方法是采用當前日期與flag = 0 date的累積最大值之間的差值:

select t.*,
       datediff(day,
                max(case when flag = 0 then date end) over (order by date),
                date
               ) as counter
from t;

請注意,這兩種方法的邏輯是不同的-盡管它們對於所提供的數據應該產生相同的結果。 對於丟失的日期,第一個只是忽略丟失的日期。 第二秒鍾將增加缺少日期的計數器。

很好-Vertica有一個非常不錯的CONDITIONAL_CHANGE_EVENT()函數,可以幫助您...

括號之間的表達式每次更改時,整數都會增加1。每次flag更改時,都會為您提供新的組標識符或PARTITION BY的條件。 因此,一個SELECT即可獲取分組信息,然后按所獲得的分組信息進行分區。 開始:

WITH
input(dt,flag) AS (
          SELECT '2019-05-03'::DATE,0
UNION ALL SELECT '2019-05-04'::DATE,1
UNION ALL SELECT '2019-05-05'::DATE,1
UNION ALL SELECT '2019-05-06'::DATE,1
UNION ALL SELECT '2019-05-07'::DATE,1
UNION ALL SELECT '2019-05-08'::DATE,0
UNION ALL SELECT '2019-05-09'::DATE,0
UNION ALL SELECT '2019-05-10'::DATE,0
UNION ALL SELECT '2019-05-11'::DATE,1
UNION ALL SELECT '2019-05-12'::DATE,1
UNION ALL SELECT '2019-05-13'::DATE,0
UNION ALL SELECT '2019-05-14'::DATE,0
UNION ALL SELECT '2019-05-15'::DATE,1
)
,
grp_input AS (
SELECT
*
, CONDITIONAL_CHANGE_EVENT(flag) OVER(ORDER BY dt) AS grp
FROM input
)
SELECT
dt
, flag
, CASE FLAG
WHEN 0 THEN 0
ELSE ROW_NUMBER() OVER(PARTITION BY grp ORDER BY dt)
END AS counter
FROM grp_input;
-- out      dt     | flag | counter 
-- out ------------+------+---------
-- out  2019-05-03 |    0 |       0
-- out  2019-05-04 |    1 |       1
-- out  2019-05-05 |    1 |       2
-- out  2019-05-06 |    1 |       3
-- out  2019-05-07 |    1 |       4
-- out  2019-05-08 |    0 |       0
-- out  2019-05-09 |    0 |       0
-- out  2019-05-10 |    0 |       0
-- out  2019-05-11 |    1 |       1
-- out  2019-05-12 |    1 |       2
-- out  2019-05-13 |    0 |       0
-- out  2019-05-14 |    0 |       0
-- out  2019-05-15 |    1 |       1
-- out (13 rows)
-- out 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM