我有一張這樣的桌子:
| ID | 部分 |
|---|---|
| 1 | 6 |
| 2 | 6 |
| 3 | 7 |
| 4 | 7 |
| 5 | 6 |
并想獲得一個分組串列,上面寫著
| 部分 | section_nr | first_id |
|---|---|---|
| 6 | 1 | 1 |
| 7 | 2 | 3 |
| 6 | 3 | 5 |
使用 ROW_NUMBER 兩次我可以獲得接近的東西:
SELECT section, ROW_NUMBER() OVER (ORDER BY id) AS section_nr, id as first_id
FROM (
SELECT id, section, ROW_NUMBER() OVER (PARTITION BY section ORDER BY id) AS nr_within
FROM X
)
WHERE nr_within = 1
| 部分 | section_nr | first_id |
|---|---|---|
| 6 | 1 | 1 |
| 7 | 2 | 3 |
...但當然缺少第二部分 6,因為 PARTITION BY 將所有部分 = 6 組合在一起。是否有可能只分組到下一節?
更一般地(關于 GROUP BY 而不是 PARTITION BY),是否有一個簡單的解決方案將(1,1,2,2,1)分組到(1,2,1)而不是(1,2)?
uj5u.com熱心網友回復:
這是一個典型的間隙和孤島問題,可以這樣解決:
with u as
(select id, section,
case when section = lag(section) over(order by id) then 0 else 1 end as grp
from X),
v as
(select id,
section,
sum(grp) over(order by id) as section_nr
from u)
select section,
section_nr,
min(id) as first_id
from v
group by section, section_nr;
section基本上,您可以通過將當前行與上面的行(按 id 排序)進行比較section來將標簽保留在有變化的列中。section每當有變化時,將此列設定為1,當沒有變化時將其設定為0。此列的滾動總和將是節號。獲取first_id是一個簡單的使用問題group by。
小提琴
uj5u.com熱心網友回復:
那是經典。
PS
如果id確實是一系列沒有間隙的整數,我們可以用它來代替rn
select section
,row_number() over (order by min(id)) as section_nr
,min(id) as first_id
from (select id
,section
,row_number() over (order by id) as rn
,row_number() over (partition by section order by id) as rn_section
from X
)
group by section
,rn - rn_section
| 部分 | SECTION_NR | FIRST_ID |
|---|---|---|
| 6 | 1 | 1 |
| 7 | 2 | 3 |
| 6 | 3 | 5 |
小提琴
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/441829.html
上一篇:檢查shell腳本中的存盤程序
