我有下表(其他几个表中的临时表)
PersonID Date Status
1337 2019-04-24 02:28:53.677 DR
1337 2019-04-24 05:23:17.410 XM
1337 2019-04-24 06:51:00.160 DR
1337 2019-04-24 12:58:02.783 DR
1337 2019-04-24 13:23:26.150 UPD
1337 2019-04-24 13:24:54.527 UPD
1337 2019-04-24 13:42:36.503 UPD
1337 2019-04-24 13:42:36.970 D
1337 2019-04-24 13:45:19.020 D
1337 2019-04-24 13:45:20.800 A
1337 2019-04-24 13:48:56.393 A
1337 2019-04-24 13:48:57.143 UPD
1337 2019-04-24 13:49:57.630 UPD
1337 2019-04-24 13:50:37.613 A
试图获得以下排名,因为我有兴趣将其分组分组
PersonID Date Status Rank
1337 2019-04-24 02:28:53.677 DR 1
1337 2019-04-24 05:23:17.410 XM 2
1337 2019-04-24 06:51:00.160 DR 3
1337 2019-04-24 12:58:02.783 DR 3
1337 2019-04-24 13:23:26.150 UPD 4
1337 2019-04-24 13:24:54.527 UPD 4
1337 2019-04-24 13:42:36.503 UPD 4
1337 2019-04-24 13:42:36.970 D 5
1337 2019-04-24 13:45:19.020 D 5
1337 2019-04-24 13:45:20.800 A 6
1337 2019-04-24 13:48:56.393 A 6
1337 2019-04-24 13:48:57.143 UPD 7
1337 2019-04-24 13:49:57.630 UPD 7
1337 2019-04-24 13:50:37.613 A 8
尝试使用
Select Time, Status,
RANK() OVER (partition by ResourceStatusCode order by ReportedDateTime ) as R1
,ROW_NUMBER() OVER(partition by ResourceStatusCode ORDER BY ReportedDateTime) as RN2
from #tbl1
order by Time
我应该尝试在每种新状态下使用另一种带有行号的方法吗?
我们的服务器(SQL Server 2008)已禁用Lead()和lag()函数,求和超过
答案 0 :(得分:1)
这里是一种更为简洁的方法,应该将您需要的内容交付给您:
declare @t table(PersonID int,DateValue datetime,Stat varchar(5));
insert into @t values (1337,'2019-04-24 02:28:53.677','DR'),(1337,'2019-04-24 05:23:17.410','XM'),(1337,'2019-04-24 06:51:00.160','DR'),(1337,'2019-04-24 12:58:02.783','DR'),(1337,'2019-04-24 13:23:26.150','UPD'),(1337,'2019-04-24 13:24:54.527','UPD'),(1337,'2019-04-24 13:42:36.503','UPD'),(1337,'2019-04-24 13:42:36.970','D'),(1337,'2019-04-24 13:45:19.020','D'),(1337,'2019-04-24 13:45:20.800','A'),(1337,'2019-04-24 13:48:56.393','A'),(1337,'2019-04-24 13:48:57.143','UPD'),(1337,'2019-04-24 13:49:57.630','UPD'),(1337,'2019-04-24 13:50:37.613','A');
with d as
(
select PersonID
,DateValue
,Stat
,row_number() over (order by DateValue,Stat) as rn
from @t
)
select d1.PersonID
,d1.DateValue
,d1.Stat
,sum(case when d1.Stat = d2.Stat then 0 else 1 end) over (order by d1.DateValue) as Ranking
from d as d1
left join d as d2
on d1.rn-1 = d2.rn
order by d1.DateValue
+----------+-------------------------+------+---------+
| PersonID | DateValue | Stat | Ranking |
+----------+-------------------------+------+---------+
| 1337 | 2019-04-24 02:28:53.677 | DR | 1 |
| 1337 | 2019-04-24 05:23:17.410 | XM | 2 |
| 1337 | 2019-04-24 06:51:00.160 | DR | 3 |
| 1337 | 2019-04-24 12:58:02.783 | DR | 3 |
| 1337 | 2019-04-24 13:23:26.150 | UPD | 4 |
| 1337 | 2019-04-24 13:24:54.527 | UPD | 4 |
| 1337 | 2019-04-24 13:42:36.503 | UPD | 4 |
| 1337 | 2019-04-24 13:42:36.970 | D | 5 |
| 1337 | 2019-04-24 13:45:19.020 | D | 5 |
| 1337 | 2019-04-24 13:45:20.800 | A | 6 |
| 1337 | 2019-04-24 13:48:56.393 | A | 6 |
| 1337 | 2019-04-24 13:48:57.143 | UPD | 7 |
| 1337 | 2019-04-24 13:49:57.630 | UPD | 7 |
| 1337 | 2019-04-24 13:50:37.613 | A | 8 |
+----------+-------------------------+------+---------+
由于您使用的是v2008,因此窗口聚合中没有order by
,因此您的选择受到限制。我真正看到的无需升级即可实现的唯一方法是使用递归cte:
declare @t table(PersonID int,DateValue datetime,Stat varchar(5));
insert into @t values (1337,'2019-04-24 02:28:53.677','DR'),(1337,'2019-04-24 05:23:17.410','XM'),(1337,'2019-04-24 06:51:00.160','DR'),(1337,'2019-04-24 12:58:02.783','DR'),(1337,'2019-04-24 13:23:26.150','UPD'),(1337,'2019-04-24 13:24:54.527','UPD'),(1337,'2019-04-24 13:42:36.503','UPD'),(1337,'2019-04-24 13:42:36.970','D'),(1337,'2019-04-24 13:45:19.020','D'),(1337,'2019-04-24 13:45:20.800','A'),(1337,'2019-04-24 13:48:56.393','A'),(1337,'2019-04-24 13:48:57.143','UPD'),(1337,'2019-04-24 13:49:57.630','UPD'),(1337,'2019-04-24 13:50:37.613','A');
with d as
(
select PersonID
,DateValue
,Stat
,row_number() over (order by DateValue,Stat) as rn
from @t
)
,r as
(
select PersonID
,DateValue
,Stat
,rn
,cast(1 as int) as Ranking
from d
where rn = 1
union all
select d.PersonID
,d.DateValue
,d.Stat
,d.rn
,case when d.Stat = r.Stat then r.Ranking else r.Ranking+1 end as Ranking
from r
join d
on r.rn+1 = d.rn
)
select PersonID
,DateValue
,Stat
,Ranking
from r
order by DateValue;
答案 1 :(得分:0)
尝试以下操作:
WITH cte AS(
SELECT PersonID,CAST([Date] AS datetime) [Date],[Status]
FROM
(VALUES
(1337,'2019-04-24 02:28:53.677','DR '),
(1337,'2019-04-24 05:23:17.410','XM '),
(1337,'2019-04-24 06:51:00.160','DR '),
(1337,'2019-04-24 12:58:02.783','DR '),
(1337,'2019-04-24 13:23:26.150','UPD'),
(1337,'2019-04-24 13:24:54.527','UPD'),
(1337,'2019-04-24 13:42:36.503','UPD'),
(1337,'2019-04-24 13:42:36.970','D '),
(1337,'2019-04-24 13:45:19.020','D '),
(1337,'2019-04-24 13:45:20.800','A '),
(1337,'2019-04-24 13:48:56.393','A '),
(1337,'2019-04-24 13:48:57.143','UPD'),
(1337,'2019-04-24 13:49:57.630','UPD'),
(1337,'2019-04-24 13:50:37.613','A ')
) v(PersonID,[Date],[Status])
)
SELECT
PersonID,
[Date],
[Status],
SUM(IsNext)OVER(PARTITION BY PersonID ORDER BY [Date],[Status])+1 [Rank]
FROM
(
SELECT *,IIF(LAG([Status])OVER(PARTITION BY PersonID ORDER BY [Date],[Status])<>[Status],1,0) IsNext
FROM cte
) q
ORDER BY PersonID,[Date],[Status]
没有LAG
的变体:
WITH cte1 AS(
SELECT PersonID,CAST([Date] AS datetime) [Date],[Status]
FROM
(VALUES
(1337,'2019-04-24 02:28:53.677','DR '),
(1337,'2019-04-24 05:23:17.410','XM '),
(1337,'2019-04-24 06:51:00.160','DR '),
(1337,'2019-04-24 12:58:02.783','DR '),
(1337,'2019-04-24 13:23:26.150','UPD'),
(1337,'2019-04-24 13:24:54.527','UPD'),
(1337,'2019-04-24 13:42:36.503','UPD'),
(1337,'2019-04-24 13:42:36.970','D '),
(1337,'2019-04-24 13:45:19.020','D '),
(1337,'2019-04-24 13:45:20.800','A '),
(1337,'2019-04-24 13:48:56.393','A '),
(1337,'2019-04-24 13:48:57.143','UPD'),
(1337,'2019-04-24 13:49:57.630','UPD'),
(1337,'2019-04-24 13:50:37.613','A ')
) v(PersonID,[Date],[Status])
),
cte2 AS(
SELECT *,ROW_NUMBER()OVER(PARTITION BY PersonID ORDER BY [Date],[Status]) N
FROM cte1
)
SELECT
PersonID,
[Date],
[Status],
SUM(IsNext)OVER(PARTITION BY PersonID ORDER BY [Date],[Status])+1 [Rank]
FROM
(
SELECT q1.*,CASE WHEN q1.[Status]<>q2.[Status] THEN 1 ELSE 0 END IsNext
FROM cte2 q1
LEFT JOIN cte2 q2 ON q1.PersonID=q2.PersonID AND q1.N=q2.N+1
) q
ORDER BY PersonID,[Date],[Status]