Sql 为每个类别N行的批次设置行号
我有一张桌子Sql 为每个类别N行的批次设置行号,sql,sql-server,sql-server-2012,row-number,Sql,Sql Server,Sql Server 2012,Row Number,我有一张桌子 +-----+----------+---------+ | 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 | Alu
+-----+----------+---------+
| 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行的下一个值。无论何时相位发生变化,它都应该转到下一个数字,即使前一个数字的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 |
+-----+----------+---------+------+
我也尝试过使用稠密的_秩,但没有得到预期的输出
select *, (row_number() over (order by phase)-1) / 3 as sets
from table_main
试一试:
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
试一试:
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
用于获取列的上一行值,如果更改,则添加1。使用%3中提到的行数,然后将这些值相加,如下所示
;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
用于获取列的上一行值,如果更改,则添加1。使用%3中提到的行数,然后将这些值相加,如下所示
;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
这个答案肯定比我的答案更清晰易懂。!!这个答案肯定比我的答案更清晰易懂。!!