我有一个名为 crampWork 的表,如下所示:
CREATE TABLE crewWork(
FloorNumber int, AptNumber int, WorkType int, simTime int )
填充表格后,我需要知道 apt 发生了多少次更改,以及 floor 发生了多少次更改。通常我希望在每个 apt 上找到 10 排,在每层楼上找到 40-50 排。 我可以为此编写一个标量函数,但我想知道是否有任何方法可以在 t-SQL 中执行此操作而无需编写标量函数。
谢谢
数据将如下所示:
FloorNumber AptNumber WorkType simTime
1 1 12 10
1 1 12 25
1 1 13 35
1 1 13 47
1 2 12 52
1 2 12 59
1 2 13 68
1 1 14 75
1 4 12 79
1 4 12 89
1 4 13 92
1 4 14 105
1 3 12 115
1 3 13 129
1 3 14 138
2 1 12 142
2 1 12 150
2 1 14 168
2 1 14 171
2 3 12 180
2 3 13 190
2 3 13 200
2 3 14 205
3 3 14 216
3 4 12 228
3 4 12 231
3 4 14 249
3 4 13 260
3 1 12 280
3 1 13 295
2 1 14 315
2 2 12 328
2 2 14 346
我需要报告信息,我不需要将其存储在任何地方。
最佳答案
如果我没有遗漏任何内容,您可以使用以下方法查找更改的数量:
确定具有相同值的后续行组;
计算这些组;
减 1。
分别为 AptNumber
和 FloorNumber
应用该方法。
可以像 this answer 中那样确定组。 ,只有在您的情况下没有 Seq
列。相反,可以使用另一个 ROW_NUMBER()
表达式。这是一个近似的解决方案:
;
WITH marked AS (
SELECT
FloorGroup = ROW_NUMBER() OVER ( ORDER BY simTime)
- ROW_NUMBER() OVER (PARTITION BY FloorNumber ORDER BY simTime),
AptGroup = ROW_NUMBER() OVER ( ORDER BY simTime)
- ROW_NUMBER() OVER (PARTITION BY AptNumber ORDER BY simTime)
FROM crewWork
)
SELECT
FloorChanges = COUNT(DISTINCT FloorGroup) - 1,
AptChanges = COUNT(DISTINCT AprGroup) - 1
FROM marked
(我在这里假设 simTime
列定义了更改的时间线。)
更新
下表显示了如何为 AptNumber
获得不同的组。
AptNumber <i>RN</i> <i>RN_Apt</i> Apt_Group (= <i>RN</i> - <i>RN_Apt</i>)
--------- -- ------ ---------
1 1 1 0
1 2 2 0
1 3 3 0
1 4 4 0
2 5 1 4
2 6 2 4
2 7 3 4
1 8 5 => 3
4 9 1 8
4 10 2 8
4 11 3 8
4 12 4 8
3 13 1 12
3 14 2 12
3 15 3 12
1 16 6 10
… … … …
这里 RN
是一个伪列,代表 ROW_NUMBER() OVER (ORDER BY simTime)
。可以看到,这只是从1开始的一系列排名。
另一个伪列,RN_Apt
包含另一个ROW_NUMBER
产生的值,即ROW_NUMBER() OVER (PARTITION BY AptNumber按 simTime 排序)
。它包含相同 AptNumber
值的各个组内的排名。您可以看到,对于新遇到的值,序列会重新开始,而对于重复出现的值,它会从上次停止的地方继续。
您还可以从表格中看到,如果我们从 RN_Apt
中减去 RN
(可能是另一个反过来,在这种情况下无关紧要),我们得到唯一标识相同 AptNumber
值的每个不同组的值。您不妨将该值称为组 ID。
所以,既然我们已经获得了这些 ID,那么我们只需计算它们(当然,计算不同的值)。那将是组的数量,并且更改的数量少了一个(假设第一组不计为更改)。
关于sql - 如何跟踪列更改其值的次数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8666295/