Sql server 2008 计算每个ID列中值的更改
我有如下数据:Sql server 2008 计算每个ID列中值的更改,sql-server-2008,tsql,count,group-by,Sql Server 2008,Tsql,Count,Group By,我有如下数据: ID | DateFrom | Value1 ########################### 1 | 01/01/2012 | VAL1 1 | 01/15/2012 | VAL1 1 | 06/01/2013 | VAL2 1 | 01/01/2014 | VAL3 2 | 01/01/2012 | VAL1 2 | 01/15/2012 | VAL1 2 | 06/01/2013
ID | DateFrom | Value1
###########################
1 | 01/01/2012 | VAL1
1 | 01/15/2012 | VAL1
1 | 06/01/2013 | VAL2
1 | 01/01/2014 | VAL3
2 | 01/01/2012 | VAL1
2 | 01/15/2012 | VAL1
2 | 06/01/2013 | VAL1
3 | 01/01/2012 | VAL2
3 | 01/15/2012 | VAL2
3 | 06/01/2013 | VAL1
我想按Value1分组,计算该值“丢失”和ID的次数,以及该值“获得”ID的次数
示例:ID 1
首先,它在2013年1月6日从VAL1变为VAL2,VAL1损失1,VAL2获得1
然后在2014年1月1日从VAL2变为VAL3,VAL2损失1,VAL3获得1
我希望像这样运行我的所有数据,计算每个值1中丢失ID的总数和获得ID的总数。像这样:
Value1 | ID Gain | ID Lost
###########################
VAL1 | 1 | 1
VAL2 | 1 | 1
VAL3 | 1 | 0
希望你们都能帮助我 你可以试试这个
WITH t AS (
SELECT
[ID], [DateFrom], [Value1]
, ROW_NUMBER() OVER (ORDER BY ID,DateFrom) AS row_num
from tbl
)
, cal AS (
SELECT t1.ID, t1.Value1 as ValueFrom, t2.Value1 AS ValueTo
FROM t t1
INNER JOIN t t2
ON t2.row_num = t1.row_num +1
WHERE t1.Value1 <> t2.Value1
)
SELECT
Value,
SUM(Gain) As IDGain,
SUM(Lost) AS IDLost
FROM
(
SELECT ValueFrom AS Value, 0 AS Gain, 1 as Lost
FROM cal
UNION ALL
SELECT ValueTo AS Value, 1 as Gain, 0 AS Lost
FROM cal
) a
GROUP BY Value
-- Source Data
declare @Src table ( id int, datefrom date, value1 nvarchar(4))
insert @Src
select * from
(values
(1 , '01.01.2012' , 'VAL1' ),
(1 , '15.01.2012' , 'VAL1' ),
(1 , '01.06.2013' , 'VAL2' ),
(1 , '01.01.2014' , 'VAL3' ),
(2 , '01.01.2012' , 'VAL1' ),
(2 , '15.01.2012' , 'VAL1' ),
(2 , '01.06.2013' , 'VAL1' ),
(3 , '01.01.2012' , 'VAL2' ),
(3 , '15.01.2012' , 'VAL2' ),
(3 , '01.06.2013' , 'VAL1' ) ) T ( ID, Date, Value )
;
WITH t AS (
SELECT
id, datefrom, value1
,ROW_NUMBER() OVER (partition by id ORDER BY datefrom,value1) as rn
from @SRC
)
, cnts AS (
select value1 = a1.value1,cnt1 = count(*) over ( partition by A1.value1) , value2 = A.Value1,cnt2 = count(*) over ( partition by A.value1)
from t A
right join t A1 on A1.id = A.ID and A1.rn = A.rn + 1
where isnull(A.value1,'') <> A1.value1
),
Gain as (
select distinct value1,cnt1 from Cnts
),
Loss as (
select distinct value2,cnt2 from Cnts
)
SELECT
Value = g.value1,
gain = g.cnt1,
loss = isnull(l.cnt2,0)
from gain g left join loss l
on g.value1 = l.value2
/* yield result
Value gain loss
VAL1 3 1
VAL2 2 2
VAL3 1 0
*/