2011-12-29 82 views
3

我有一个名为crewWork表如下:如何追踪一列的值改变了多少次?

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

被填充了表后,我需要知道多少次发生在容易改变多少次发生在地板上的变化。通常我希望在每个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 

我需要一个报告中的信息,我并不需要存储任何地方。

+0

您可以添加样品数据,输入和输出吗? – gbn 2011-12-29 09:59:55

+1

变化是如何表示的?作为一个新的行? (如果你没有把它存储在某个地方不知道你期望标量函数如何帮助...) – 2011-12-29 10:00:26

+1

可能的重复[如何跟踪列中发生的变化数量? T-SQL - SQL Server](http://stackoverflow.com/questions/2736934/how-to-track-number-of-changes-occured-in-a-column-t-sql-sql-server) – 2011-12-29 10:01:25

回答

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列定义变化的时间表。)


UPDATE

下面是示出了不同的组是如何用于AptNumber得到的表。

AptNumber RNRN_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值的单个组内的排名。您可以看到,对于新遇到的值,序列重新开始,对于重复的序列,它会继续上一次停止的位置。

您也可以从表中可以看到,如果我们减去RNRN_Apt(可能是倒过来,不会在这种情况下重要),我们得到一个唯一标识的每一个独特的群体价值相同的AptNumber值。您不妨将该值称为组ID。

所以,现在我们已经得到了这些ID,它只是对我们的计数(当然,计数不同的值)。这将是组的数量,并且更改的次数少一次(假设第一组不计为更改)。

+0

例如,您能详细说明如何获得AptGroup吗? – b3bel 2011-12-29 14:50:34

+0

AptGroup也应该考虑楼层,因为#1楼的公寓#1不同于#2楼#1的公寓# – 2011-12-29 15:29:07

+0

@ b3bel:更新了我的回答。 – 2011-12-29 15:35:10

2

添加一个额外的列changecount

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

增量changecount值为每个更新用

如果想知道计数的每个字段,然后添加与之对应列changecount

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