如何在SQL中跟踪值的迭代

时间:2019-04-29 19:08:32

标签: sql sql-server

我正在尝试使用SSMS 2017跟踪制造过程中刀片的使用情况。将刀片装入产品并在产品上使用,直到发现其变钝为止,然后将其取出以进行锐化,同时用另一个刀片替换它。我们有30个刀片可以循环使用和磨尖。

使用一个提供产品批号(顺序)和刀片名称的表,我想将每批使用的刀片名称分为几组。

我的sql技能非常基础,因此我一直在尝试row_number,rank和一些使用超前/滞后功能的尝试。到目前为止,这仅使我能够根据刀片名称将每个产品分解为订单,并确定进行刀片更换的产品。我觉得这可能很有用,但是我很难弄清楚该怎么做。

我希望能够为使用刀片迭代制造的每组产品分配一个标识号。例如:

LotNo   BladeID Iteration
418211  BH40    1
418212  BH40    1
418213  BH40    1
418214  ES11    2
418215  ES11    2
418216  BH40    3

我目前能够产生以下错误结果:

使用:

SELECT b.LotNo,
       b.BladeID,
       ROW_NUMBER() OVER (PARTITION BY b.BladeID ORDER BY b.BladeID)
FROM blades AS b
ORDER BY b.LotNo ASC;

我得到:

LotNo   BladeID Iteration
418211  BH40    1
418212  BH40    2
418213  BH40    3
418214  ES11    1
418215  ES11    2
418216  BH40    4

2 个答案:

答案 0 :(得分:1)

这是您问题的可能解决方案。它首先创建一系列组,以标识何时必须更改编号。然后,它得到一个命令,为每个组分配正确的值。最后,它为迭代分配值。我以一种可消耗的方式包含样本数据,以便任何人都可以将其用于测试目的。

CREATE TABLE #Sample(
    LotNo     int,
    BladeID   varchar(10),
    Iteration int
);
INSERT INTO #Sample
VALUES
(418211, 'BH40', 1),
(418212, 'BH40', 1),
(418213, 'BH40', 1),
(418214, 'ES11', 2),
(418215, 'ES11', 2),
(418216, 'BH40', 3);
GO

WITH cteGroups AS(
    SELECT *,
        ROW_NUMBER() OVER(ORDER BY LotNo) - ROW_NUMBER() OVER(PARTITION BY BladeID ORDER BY LotNo) AS island
    FROM #Sample
),
cteOrdering AS(
    SELECT *, MIN( LotNo) OVER( PARTITION BY island, BladeID) AS OrderCol
    FROM cteGroups
)
SELECT LotNo,
    BladeID,
    Iteration,
    DENSE_RANK() OVER( ORDER BY OrderCol) AS IterationCalc
FROM cteOrdering;

答案 1 :(得分:0)

您可以使用lag()和累计金额来完成此操作:

select s.*,
       sum(case when prev_BladeID = BladeId then 0 else 1 end) over (order by LotNo) as Iteration
from (select s.*,
             lag(s.BladeID) over (order by s.LotNo) as prev_BladeID
      from #sample s
     ) s;

除了比行号的区别更简单之外,我认为这在概念上也更简单。这只是在计算BladeID从一手更改为另一手的次数。