Let*_*ogo 4 sql t-sql sql-server row-number gaps-and-islands
我有一个问题,我想分区排序表.有没有办法可以做到这一点?
我正在使用SQL Server 2016.
输入表:
|---------|-----------------|-----------|------------|
| prod | sortcolumn | type | value |
|---------|-----------------|-----------|------------|
| X | 1 | P | 12 |
| X | 2 | P | 23 |
| X | 3 | E | 34 |
| X | 4 | P | 45 |
| X | 5 | E | 56 |
| X | 6 | E | 67 |
| Y | 1 | P | 78 |
|---------|-----------------|-----------|------------|
Run Code Online (Sandbox Code Playgroud)
期望的输出
|---------|-----------------|-----------|------------|------------|
| prod | sortcolumn | type | value | rowNr |
|---------|-----------------|-----------|------------|------------|
| X | 1 | P | 12 | 1 |
| X | 2 | P | 23 | 2 |
| X | 3 | E | 34 | 1 |
| X | 4 | P | 45 | 1 |
| X | 5 | E | 56 | 1 |
| X | 6 | E | 67 | 2 |
| Y | 1 | P | 78 | 1 |
|---------|-----------------|-----------|------------|------------|
Run Code Online (Sandbox Code Playgroud)
我到目前为止:
SELECT
table.*,
ROW_NUMBER() OVER(PARTITION BY table.prod, table.type ORDER BY table.sortColumn) rowNr
FROM table
Run Code Online (Sandbox Code Playgroud)
但是这不会重新启动第4行的行号,因为它是相同的产品和类型.我怎样才能重新启动每个产品以及基于排序标准的每种类型更改,即使类型更改回原先已有的类型?这是否可以使用ROW_NUMBER函数,或者我是否必须使用LEAD和LAG和CASES(这可能会使它非常慢,对吧?)
谢谢!
这是一个空白和岛屿问题.您可以使用以下查询:
SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY prod ORDER BY sortcolumn)
-
ROW_NUMBER() OVER (PARTITION BY prod, type ORDER BY sortcolumn) AS grp
FROM mytable t
Run Code Online (Sandbox Code Playgroud)
要得到:
prod sortcolumn type value grp
----------------------------------------
X 1 P 12 0
X 2 P 23 0
X 3 E 34 2
X 4 P 45 1
X 5 E 56 3
X 6 E 67 3
Y 1 P 78 0
Run Code Online (Sandbox Code Playgroud)
现在,字段grp可用于分区:
;WITH IslandsCTE AS (
SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY prod ORDER BY sortcolumn)
-
ROW_NUMBER() OVER (PARTITION BY prod, type ORDER BY sortcolumn) AS grp
FROM mytable t
)
SELECT prod, sortcolumn, type, value,
ROW_NUMBER() OVER (PARTITION BY prod, type, grp ORDER BY sortcolumn) AS rowNr
FROM IslandsCTE
ORDER BY prod, sortcolumn
Run Code Online (Sandbox Code Playgroud)