如何跟踪列更改其值的次数?

时间:2011-12-29 09:56:55

标签: sql sql-server sql-server-2008 tsql

我有一张名为crewWork的表格如下:

CREATE TABLE crewWork( 
       FloorNumber int, AptNumber int, WorkType int, simTime int )

在填充表格之后,我需要知道apt发生了多少次变化以及楼层变化发生了多少次。通常我希望在每个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  

我需要报告的信息,我不需要将它存储在任何地方。

3 个答案:

答案 0 :(得分:5)

如果我没有遗漏任何内容,您可以使用以下方法查找更改次数:

  • 确定具有相同值的后续行组;

  • 统计这些群体;

  • 减去1。

AptNumberFloorNumber单独应用此方法。

可以像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  RN  RN_Apt  Apt_Group (= RN - RN_Apt)
---------  --  ------  ---------
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 ORDER BY simTime)。它包含具有相同AptNumber值的各个组中的排名。您可以看到,对于新遇到的值,序列重新开始,对于重复的序列,它会在上次停止的位置继续。

您还可以从表格中看到,如果我们从 RN 中减去 RN_Apt (可能是相反的,不是在这种情况下,我们得到的值唯一地标识了相同AptNumber值的每个不同组。您也可以将该值称为组ID。

所以,既然我们已经拥有了这些ID,那么我们只能计算它们(当然,计算不同的值)。这将是组的数量,并且更改的数量减少一个(假设第一组不计入更改)。

答案 1 :(得分:2)

添加额外的列changecount

CREATE TABLE crewWork( 
       FloorNumber int, AptNumber int, WorkType int, simTime int ,changecount int)
每次更新

增加changecount

如果想知道每个字段的计数,则为changecount添加与其对应的列

答案 2 :(得分:1)

假设每条记录代表不同的变化,您可以通过以下方式找到每层的变化:

select FloorNumber, count(*)
from crewWork
group by FloorNumber

每间公寓的变化(假设AptNumber唯一标识公寓):

select AptNumber, count(*)
from crewWork
group by AptNumber

或者(假设AptNumber和FloorNumber一起唯一标识公寓):

select FloorNumber, AptNumber, count(*)
from crewWork
group by FloorNumber, AptNumber