使用分区计算 SQL 中的过程重复
Counting Process Repetitions in SQL using Partitioning
仅供参考 - 我真的不确定给这个问题起什么标题。欢迎任何指导。
下面我有一块 "parent" 地毯 (A12345),它最终被切成 2 块或更多块地毯。这些地毯需要经过严格的洗涤,我需要知道在 "Parent" 和 "Child" 之间地毯经过了多少次洗涤。
所以总的来说,"A12345-678"在切割前洗涤了 4 次,然后在分离后洗涤了 3 次。
使用序列号,我必须能够将流程标记为第 1、第 2、第 3 等...Process_Num 列是我想要实现的所需列SQL.
Rug_Num Sequence_Num Process Process_Num
A12345 10 Wash 1st Wash
A12345 11 Wash 2nd Wash
A12345 30 Wash 4th Wash
A12345 20 Wash 3rd Wash
'----Rug cut into 2 child rugs'
A12345-678 40 Wash 5th Wash
A12345-678 50 Wash 6th Wash
A12345-678 60 Wash 7th Wash
A12345-997 40 Wash 5th Wash
A12345-997 50 Wash 6th Wash
A12345-997 60 Wash 7th Wash
A12345-997 70 Wash 8th Wash
这是我的 "in-progress" 语句,但我不知道如何在 "THEN" 之后添加一些内容,这将导致它按顺序将当前序列编号为“1st、2nd、3rd”。我的想法是在第一个 THEN
之后再放一个 COUNT CASE WHEN
但这将是一个无限的陈述。
WITH toupdate AS (
SELECT m.*,
count(CASE WHEN (m.Process = 'Wash'
AND m.Rug_Num = m.Rug_Num
AND m.sequence_num < m.sequence_num)
THEN 1 ELSE 0 END)
OVER (PARTITION BY m.Process, m.Rug_Num, m.Process_Num) AS Process_Num_New
FROM mfng_data m
)
UPDATE toupdate
SET Process_Num = ISNULL(Process_Num_New,0);
所以上面我试图在 SQL 中复制一个 COUNTIFS
(Excel)。 Excel 示例如下。 H列的公式为:
=(COUNTIFS($C:$C,C3,$D:$D,"<"&D3,$E:$E,"Wash")+1)+IF(LEN(C3)>6,COUNTIFS($C:$C,$C,$E:$E,"Wash"),0)
我添加了 +1,这样它就会计算出比当前序列少的数量,并为当前序列加 1。
您可以将 count(*)
与 window 函数一起使用 over()
下面的查询中有 2 个 count()
。第一个计算 parent 的洗涤编号,第二个 count()
在 child
select *,
Wash_No = count (case when Parent_Rug = Rug_Num then 1 end)
over (partition by Parent_Rug order by Sequence_num)
+ count (case when Parent_Rug <> Rug_Num then 1 end)
over (partition by Rug_Num order by Sequence_num)
from mfng_data
尝试使用以下方式
CREATE TABLE TestTable(
Rug_Num varchar(10),
Sequence_Num int,
Process varchar(10),
Process_Num int
)
INSERT TestTable(Rug_Num,Sequence_Num,Process)VALUES
('A12345', 10,'Wash')
,('A12345', 11,'Wash')
,('A12345', 30,'Wash')
,('A12345', 20,'Wash')
,('A12345-678',40,'Wash')
,('A12345-678',50,'Wash')
,('A12345-678',60,'Wash')
,('A12345-997',40,'Wash')
,('A12345-997',50,'Wash')
,('A12345-997',60,'Wash')
,('A12345-997',70,'Wash')
;WITH numCTE AS(
SELECT Sequence_Num,ROW_NUMBER()OVER(ORDER BY Sequence_Num) Process_Num
FROM
(
SELECT DISTINCT Sequence_Num
FROM TestTable
) q
)
UPDATE t
SET
t.Process_Num=n.Process_Num
FROM TestTable t
JOIN numCTE n ON t.Sequence_Num=n.Sequence_Num
SELECT *
FROM TestTable
仅供参考 - 我真的不确定给这个问题起什么标题。欢迎任何指导。
下面我有一块 "parent" 地毯 (A12345),它最终被切成 2 块或更多块地毯。这些地毯需要经过严格的洗涤,我需要知道在 "Parent" 和 "Child" 之间地毯经过了多少次洗涤。
所以总的来说,"A12345-678"在切割前洗涤了 4 次,然后在分离后洗涤了 3 次。
使用序列号,我必须能够将流程标记为第 1、第 2、第 3 等...Process_Num 列是我想要实现的所需列SQL.
Rug_Num Sequence_Num Process Process_Num
A12345 10 Wash 1st Wash
A12345 11 Wash 2nd Wash
A12345 30 Wash 4th Wash
A12345 20 Wash 3rd Wash
'----Rug cut into 2 child rugs'
A12345-678 40 Wash 5th Wash
A12345-678 50 Wash 6th Wash
A12345-678 60 Wash 7th Wash
A12345-997 40 Wash 5th Wash
A12345-997 50 Wash 6th Wash
A12345-997 60 Wash 7th Wash
A12345-997 70 Wash 8th Wash
这是我的 "in-progress" 语句,但我不知道如何在 "THEN" 之后添加一些内容,这将导致它按顺序将当前序列编号为“1st、2nd、3rd”。我的想法是在第一个 THEN
之后再放一个 COUNT CASE WHEN
但这将是一个无限的陈述。
WITH toupdate AS (
SELECT m.*,
count(CASE WHEN (m.Process = 'Wash'
AND m.Rug_Num = m.Rug_Num
AND m.sequence_num < m.sequence_num)
THEN 1 ELSE 0 END)
OVER (PARTITION BY m.Process, m.Rug_Num, m.Process_Num) AS Process_Num_New
FROM mfng_data m
)
UPDATE toupdate
SET Process_Num = ISNULL(Process_Num_New,0);
所以上面我试图在 SQL 中复制一个 COUNTIFS
(Excel)。 Excel 示例如下。 H列的公式为:
=(COUNTIFS($C:$C,C3,$D:$D,"<"&D3,$E:$E,"Wash")+1)+IF(LEN(C3)>6,COUNTIFS($C:$C,$C,$E:$E,"Wash"),0)
我添加了 +1,这样它就会计算出比当前序列少的数量,并为当前序列加 1。
您可以将 count(*)
与 window 函数一起使用 over()
下面的查询中有 2 个 count()
。第一个计算 parent 的洗涤编号,第二个 count()
在 child
select *,
Wash_No = count (case when Parent_Rug = Rug_Num then 1 end)
over (partition by Parent_Rug order by Sequence_num)
+ count (case when Parent_Rug <> Rug_Num then 1 end)
over (partition by Rug_Num order by Sequence_num)
from mfng_data
尝试使用以下方式
CREATE TABLE TestTable(
Rug_Num varchar(10),
Sequence_Num int,
Process varchar(10),
Process_Num int
)
INSERT TestTable(Rug_Num,Sequence_Num,Process)VALUES
('A12345', 10,'Wash')
,('A12345', 11,'Wash')
,('A12345', 30,'Wash')
,('A12345', 20,'Wash')
,('A12345-678',40,'Wash')
,('A12345-678',50,'Wash')
,('A12345-678',60,'Wash')
,('A12345-997',40,'Wash')
,('A12345-997',50,'Wash')
,('A12345-997',60,'Wash')
,('A12345-997',70,'Wash')
;WITH numCTE AS(
SELECT Sequence_Num,ROW_NUMBER()OVER(ORDER BY Sequence_Num) Process_Num
FROM
(
SELECT DISTINCT Sequence_Num
FROM TestTable
) q
)
UPDATE t
SET
t.Process_Num=n.Process_Num
FROM TestTable t
JOIN numCTE n ON t.Sequence_Num=n.Sequence_Num
SELECT *
FROM TestTable