为每个类别的 N 行批次设置行号
Set row number for batch of N rows per category
我有table
+-----+----------+---------+
| id | name | phase |
+-----+----------+---------+
| 101 | Bolt | PHASE 1 |
| 102 | Nut | PHASE 1 |
| 103 | Screw | PHASE 1 |
| 104 | Hex BOLT | PHASE 1 |
| 105 | Rubber | PHASE 1 |
| 106 | Aluminum | PHASE 2 |
| 107 | Slate | PHASE 2 |
| 108 | Pen | PHASE 3 |
| 109 | Pencil | PHASE 3 |
| 110 | Mouse | PHASE 3 |
| 111 | Keyboard | PHASE 3 |
+-----+----------+---------+
我想创建另一个列,我必须在其中输入行号。
逻辑:
对于 3 行,它应该相同并更改为第 4 行的下一个值。每当 PHASE 发生变化时,它应该转到下一个数字,即使前一个数字的 3 组不完整。
预期输出
+-----+----------+---------+-----+
| id | name | phase | SET |
+-----+----------+---------+-----+
| 101 | Bolt | PHASE 1 | 1 |
| 102 | Nut | PHASE 1 | 1 |
| 103 | Screw | PHASE 1 | 1 |
| 104 | Hex BOLT | PHASE 1 | 2 |
| 105 | Rubber | PHASE 1 | 2 |
| 106 | Aluminum | PHASE 2 | 3 |
| 107 | Slate | PHASE 2 | 3 |
| 108 | Pen | PHASE 3 | 4 |
| 109 | Pencil | PHASE 3 | 4 |
| 110 | Mouse | PHASE 3 | 4 |
| 111 | Keyboard | PHASE 3 | 5 |
+-----+----------+---------+-----+
我试过下面的查询,但它没有给我所需的输出。
select *, (row_number() over (order by phase)-1) / 3 as sets
from table_main
实际输出:
+-----+----------+---------+------+
| id | name | phase | sets |
+-----+----------+---------+------+
| 101 | Bolt | PHASE 1 | 0 |
| 102 | Nut | PHASE 1 | 0 |
| 103 | Screw | PHASE 1 | 0 |
| 104 | Hex BOLT | PHASE 1 | 1 |
| 105 | Rubber | PHASE 1 | 1 |
| 106 | Aluminum | PHASE 2 | 1 |
| 107 | Slate | PHASE 2 | 2 |
| 108 | Pen | PHASE 3 | 2 |
| 109 | Pencil | PHASE 3 | 2 |
| 110 | Mouse | PHASE 3 | 3 |
| 111 | Keyboard | PHASE 3 | 3 |
+-----+----------+---------+------+
我也尝试过 DENSE_RANK()
但没有得到预期的输出。
试一试:
WITH CTE
as
(
select *, ROW_NUMBER () OVER (PARTITION BY phase ORDER BY id) as rn
from table_main
)
SELECT *,DENSE_RANK() over (ORDER BY phase ,CEILING(rn/3.0)) as set
FROM CTE
使用 LAG
获取 column
的前一行值,如果它发生变化则添加 1
。使用 %3
中提到的 ROW_NUMBER()
,然后 sum
这些值如下所示。
;WITH tm AS (
SELECT *,
IIF((LAG(phase, 1) OVER (ORDER BY phase, id)) = phase, 0, 1) AS phase_change,
IIF((ROW_NUMBER() OVER (PARTITION BY phase ORDER BY phase)-1)%3 = 0, 1, 0) AS [set]
FROM table_main
)
SELECT id,
name,
phase,
SUM(IIF([set] > phase_change, [set], phase_change)) OVER (ORDER BY phase, id) AS [set]
FROM tm
我有table
+-----+----------+---------+
| id | name | phase |
+-----+----------+---------+
| 101 | Bolt | PHASE 1 |
| 102 | Nut | PHASE 1 |
| 103 | Screw | PHASE 1 |
| 104 | Hex BOLT | PHASE 1 |
| 105 | Rubber | PHASE 1 |
| 106 | Aluminum | PHASE 2 |
| 107 | Slate | PHASE 2 |
| 108 | Pen | PHASE 3 |
| 109 | Pencil | PHASE 3 |
| 110 | Mouse | PHASE 3 |
| 111 | Keyboard | PHASE 3 |
+-----+----------+---------+
我想创建另一个列,我必须在其中输入行号。
逻辑: 对于 3 行,它应该相同并更改为第 4 行的下一个值。每当 PHASE 发生变化时,它应该转到下一个数字,即使前一个数字的 3 组不完整。
预期输出
+-----+----------+---------+-----+
| id | name | phase | SET |
+-----+----------+---------+-----+
| 101 | Bolt | PHASE 1 | 1 |
| 102 | Nut | PHASE 1 | 1 |
| 103 | Screw | PHASE 1 | 1 |
| 104 | Hex BOLT | PHASE 1 | 2 |
| 105 | Rubber | PHASE 1 | 2 |
| 106 | Aluminum | PHASE 2 | 3 |
| 107 | Slate | PHASE 2 | 3 |
| 108 | Pen | PHASE 3 | 4 |
| 109 | Pencil | PHASE 3 | 4 |
| 110 | Mouse | PHASE 3 | 4 |
| 111 | Keyboard | PHASE 3 | 5 |
+-----+----------+---------+-----+
我试过下面的查询,但它没有给我所需的输出。
select *, (row_number() over (order by phase)-1) / 3 as sets
from table_main
实际输出:
+-----+----------+---------+------+
| id | name | phase | sets |
+-----+----------+---------+------+
| 101 | Bolt | PHASE 1 | 0 |
| 102 | Nut | PHASE 1 | 0 |
| 103 | Screw | PHASE 1 | 0 |
| 104 | Hex BOLT | PHASE 1 | 1 |
| 105 | Rubber | PHASE 1 | 1 |
| 106 | Aluminum | PHASE 2 | 1 |
| 107 | Slate | PHASE 2 | 2 |
| 108 | Pen | PHASE 3 | 2 |
| 109 | Pencil | PHASE 3 | 2 |
| 110 | Mouse | PHASE 3 | 3 |
| 111 | Keyboard | PHASE 3 | 3 |
+-----+----------+---------+------+
我也尝试过 DENSE_RANK()
但没有得到预期的输出。
试一试:
WITH CTE
as
(
select *, ROW_NUMBER () OVER (PARTITION BY phase ORDER BY id) as rn
from table_main
)
SELECT *,DENSE_RANK() over (ORDER BY phase ,CEILING(rn/3.0)) as set
FROM CTE
使用 LAG
获取 column
的前一行值,如果它发生变化则添加 1
。使用 %3
中提到的 ROW_NUMBER()
,然后 sum
这些值如下所示。
;WITH tm AS (
SELECT *,
IIF((LAG(phase, 1) OVER (ORDER BY phase, id)) = phase, 0, 1) AS phase_change,
IIF((ROW_NUMBER() OVER (PARTITION BY phase ORDER BY phase)-1)%3 = 0, 1, 0) AS [set]
FROM table_main
)
SELECT id,
name,
phase,
SUM(IIF([set] > phase_change, [set], phase_change)) OVER (ORDER BY phase, id) AS [set]
FROM tm