SQL第一个命令,然后在over子句中分区

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(这可能会使它非常慢,对吧?)

谢谢!

Gio*_*sos 5

这是一个空白和岛屿问题.您可以使用以下查询:

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)

在这里演示