在下面的示例表中,我需要一个脚本,以便在第一个S实例之前返回event_type CP的最后一个实例(如果适用)。主要比较是最近的event_date。 如果重复日期,则平局断路器将是最高的event_id。
person_id event_date event_id event_type
78 08/12/2010 00:00 706 CP
78 09/12/2010 00:00 707 CP
107 23/02/2010 00:00 93 CP
107 21/09/2012 00:00 1474 S
217 18/02/2010 00:00 158 S
364 26/01/2011 00:00 1122 CP
364 19/02/2011 00:00 569 S
367 21/06/2010 00:00 151 CP
367 01/07/2010 00:00 247 S
369 26/07/2010 00:00 248 S
369 27/07/2010 00:00 152 CP
481 07/09/2010 00:00 194 CP
481 07/09/2010 00:00 289 S
502 13/08/2010 00:00 200 CP
530 14/06/2010 00:00 220 CP
535 05/07/2010 00:00 222 CP
535 26/07/2010 00:00 224 CP
536 23/08/2010 00:00 225 CP
631 15/12/2009 00:00 256 CP
632 18/09/2010 00:00 259 CP
643 18/09/2010 00:00 261 CP
653 30/09/2010 00:00 360 S
653 15/10/2010 00:00 295 CP
653 15/10/2010 00:00 298 CP
680 30/09/2010 00:00 281 CP
680 30/11/2010 00:00 480 CP
689 06/10/2010 00:00 372 S
689 02/11/2010 00:00 306 CP
689 02/11/2010 00:00 370 CP
689 26/08/2011 00:00 1944 CP
689 27/08/2011 00:00 1947 CP
689 22/09/2011 00:00 2125 CP
689 06/11/2012 00:00 2720 CP
689 13/11/2012 00:00 2752 CP
689 15/11/2012 00:00 2765 CP
729 15/09/2010 00:00 299 CP
811 27/10/2010 00:00 413 S
834 06/01/2012 00:00 1233 S
849 21/02/2011 00:00 336 CP
984 13/11/2010 00:00 384 CP
984 18/11/2010 00:00 392 CP
984 18/11/2010 00:00 395 CP
984 19/11/2010 00:00 394 CP
1066 11/11/2010 00:00 472 S
1066 23/11/2010 00:00 408 CP
1109 23/12/2010 00:00 428 CP
1109 19/07/2011 00:00 958 S
1190 02/12/2010 00:00 499 CP
1193 03/12/2010 00:00 504 CP
1194 03/12/2010 00:00 505 CP
1199 19/11/2010 00:00 511 CP
1199 19/11/2010 00:00 501 S
1199 05/12/2010 00:00 526 CP
1199 08/12/2010 00:00 568 CP
1199 16/12/2010 00:00 704 CP
1199 16/12/2010 00:00 705 CP
1199 23/12/2010 00:00 803 CP
1199 24/12/2010 00:00 809 CP
1199 31/12/2010 00:00 851 CP
1199 11/01/2011 00:00 926 CP
1199 15/02/2011 00:00 1119 CP
1199 03/03/2011 00:00 1116 CP
1199 28/07/2011 00:00 1726 CP
1199 26/08/2011 00:00 1943 CP
1199 03/09/2011 00:00 1984 CP
1199 21/09/2011 00:00 2064 CP
1209 05/12/2010 00:00 524 CP
1210 05/12/2010 00:00 525 CP
1383 20/12/2010 00:00 798 CP
1386 20/12/2010 00:00 799 CP
1404 23/12/2010 00:00 801 CP
1405 23/12/2010 00:00 802 CP
1444 31/12/2010 00:00 849 CP
1445 31/12/2010 00:00 850 CP
1535 11/01/2011 00:00 924 CP
1536 11/01/2011 00:00 925 CP
1565 09/01/2011 00:00 979 CP
1623 27/01/2011 00:00 531 S
1661 25/01/2011 00:00 1046 CP
1662 25/01/2011 00:00 1047 CP
1663 25/01/2011 00:00 1048 CP
1665 25/01/2011 00:00 1049 CP
1666 23/01/2011 00:00 1050 CP
1667 01/02/2011 00:00 1052 CP
1741 14/02/2011 00:00 1111 CP
1752 15/02/2011 00:00 1118 CP
1781 04/10/2010 00:00 1868 CP
1781 04/10/2010 00:00 1869 CP
1781 04/10/2010 00:00 1870 CP
1781 10/02/2011 00:00 1052 S
1781 25/03/2011 00:00 1867 CP
1781 26/09/2011 00:00 2103 CP
1841 02/02/2011 00:00 1165 CP
1841 28/02/2011 00:00 597 S
1845 13/06/2011 00:00 1608 CP
1845 14/06/2011 00:00 1605 CP
1845 16/06/2011 00:00 1602 CP
1845 16/06/2011 00:00 1609 CP
1845 16/06/2011 00:00 1610 CP
1880 22/07/2011 00:00 1684 CP
1887 11/03/2011 00:00 1231 CP
1887 18/03/2011 00:00 607 S
1903 02/06/2011 00:00 1551 CP
1913 25/03/2011 00:00 1301 CP
1913 31/03/2011 00:00 1354 CP
2054 11/05/2011 00:00 1447 CP
2054 12/05/2011 00:00 780 S
2103 03/04/2011 00:00 1417 CP
2109 17/04/2011 00:00 1422 CP
2123 09/04/2011 00:00 1434 CP
2123 05/05/2011 00:00 769 S
2187 20/01/2011 00:00 1475 CP
2187 29/01/2011 00:00 803 S
2222 12/05/2011 00:00 1501 CP
2246 31/05/2011 00:00 1536 CP
2246 02/06/2011 00:00 1539 CP
2246 01/07/2012 00:00 1448 S
2246 29/07/2012 00:00 2569 CP
2246 06/08/2012 00:00 2586 CP
2306 06/05/2011 00:00 918 S
2456 15/09/2011 00:00 2065 CP
2456 02/12/2013 00:00 1694 S
2456 29/01/2014 00:00 3340 CP
2456 01/10/2014 00:00 3661 CP
2459 24/08/2011 00:00 1859 CP
2476 17/08/2011 00:00 1039 S
2512 17/09/2011 00:00 2049 CP
2512 26/01/2012 00:00 1256 S
2516 24/08/2011 00:00 1857 CP
2630 03/09/2011 00:00 1982 CP
2630 13/05/2013 00:00 3064 CP
2691 22/09/2011 00:00 2135 CP
2694 20/04/2011 00:00 2053 CP
2694 30/04/2011 00:00 1112 S
2759 07/11/2011 00:00 1165 S
2759 09/01/2012 00:00 2271 CP
2759 09/02/2012 00:00 2377 CP
2773 24/01/2013 00:00 2920 CP
2773 25/01/2013 00:00 1430 S
2773 14/02/2013 00:00 2946 CP
2858 27/10/2011 00:00 2209 CP
2858 08/11/2011 00:00 1167 S
2892 05/11/2011 00:00 1172 S
2896 09/11/2011 00:00 1174 S
2961 15/08/2012 00:00 2591 CP
3041 28/03/2012 00:00 2441 CP
3041 29/03/2012 00:00 2442 CP
3178 08/09/2012 00:00 2611 CP
3251 13/11/2012 00:00 2744 CP
3263 28/11/2012 00:00 2802 CP
3294 14/12/2012 00:00 2826 CP
3311 01/02/2013 00:00 1534 S
3344 30/04/2013 00:00 1566 S
3344 03/05/2013 00:00 3045 CP
3362 07/02/2013 00:00 2980 CP
3362 06/04/2013 00:00 1555 S
3426 22/05/2013 00:00 3086 CP
3457 29/11/2012 00:00 1574 S
3612 10/11/2012 00:00 3551 CP
3770 03/01/2014 00:00 3379 CP
3770 10/01/2014 00:00 1766 S
3805 04/03/2014 00:00 1782 S
3881 05/04/2014 00:00 3550 CP
3901 15/02/2014 00:00 3584 CP
3901 02/03/2014 00:00 1820 S
3907 04/11/2013 00:00 1821 S
3907 06/01/2014 00:00 3591 CP
3907 14/01/2014 00:00 3592 CP
3907 14/01/2014 00:00 3593 CP
4040 10/05/2014 00:00 3660 CP
4040 15/05/2014 00:00 3659 CP
4040 20/05/2014 00:00 1866 S
答案 0 :(得分:1)
使用ROW_NUMBER()的示例,SQL Server 2005支持:
[编辑:如果您的真实数据集的情况下某些person_id没有S类型或者某些person_id的S的多个实例(这将获得S的第一个实例且只有其他代码),此版本稍微强一些在第一个实例之前)]
with tab as
(
select 3907 as person_id, 2457 as event_id, '01/09/2013 00:00' as event_date, 'CP' as event_type
union
select 3907 as person_id, 2896 as event_id, '09/09/2013 00:00' as event_date, 'CP' as event_type
union
select 3907 as person_id, 1866 as event_id, '20/05/2014 00:00' as event_date, 'S' as event_type
union
select 4040 as person_id, 3660 as event_id, '10/05/2014 00:00' as event_date, 'CP' as event_type
union
select 4040 as person_id, 3659 as event_id, '15/05/2014 00:00' as event_date, 'CP' as event_type
union
select 4040 as person_id, 1866 as event_id, '20/05/2014 00:00' as event_date, 'S' as event_type
)
,personsAndFirst_S_Type as
(
select
person_id,
min(event_date) as first_S_EventDate
from tab
where event_type = 'S'
group by person_id
)
,
numberedTab as
(
select
*,
ROW_NUMBER() OVER(PARTITION BY person_id ORDER BY event_type, event_date, event_id) as rn
from tab
)
,maxRn as
(
select
person_id,
max(rn) as maxNonSRow
from numberedTab nt
where nt.event_type <> 'S'
group by person_id
)
select
numberedTab.person_id,
numberedTab.event_id,
numberedTab.event_date,
numberedTab.event_type
from numberedTab
inner join maxRn
on numberedTab.rn = maxRn.maxNonSRow
and numberedTab.person_id = maxRn.person_id
inner join personsAndFirst_S_Type s
on numberedTab.person_id = s.person_id
and numberedTab.event_date < s.first_S_EventDate
使用TSQL的Lead函数根据您要分区和排序这些分区的每一行获取下一行的event_type列。
MSDN Page on TSQL LEAD Function
with tab as
(
select 3907 as person_id, 2457 as event_id, '01/09/2013 00:00' as event_date, 'CP' as event_type
union
select 3907 as person_id, 2896 as event_id, '09/09/2013 00:00' as event_date, 'CP' as event_type
union
select 3907 as person_id, 1866 as event_id, '20/05/2014 00:00' as event_date, 'S' as event_type
union
select 4040 as person_id, 3660 as event_id, '10/05/2014 00:00' as event_date, 'CP' as event_type
union
select 4040 as person_id, 3659 as event_id, '15/05/2014 00:00' as event_date, 'CP' as event_type
union
select 4040 as person_id, 1866 as event_id, '20/05/2014 00:00' as event_date, 'S' as event_type
),
tabWithNextEventTypeOnRow as
(
select
*,
LEAD(event_type) OVER(PARTITION BY person_id ORDER BY event_date) as nxtEventType
from tab
)
select
*
from tabWithNextEventTypeOnRow
where nxtEventType = 'S'
答案 1 :(得分:0)
您可以使用not exists
在第一个CP
和S
之前选择所有row_number()
,以选择这些行的最后CP
个(即最后一个CP
第一个S
之前的{1}}
select * from (
select *,
row_number() over (partition by person_id order by event_date desc) rn
from (
select *
from mytable t1
where not exists (
select 1 from mytable t2
where t2.event_type = 'S'
and t2.person_id = t1.person_id
and t2.event_date < t1.event_date
) and event_type = 'CP'
) t1
) t1 where rn = 1
答案 2 :(得分:0)
如果我理解正确,那么这就是你想要的。
<强>模式强>
Declare @table1 table (person_id int, event_id int, event_date varchar(30), event_type varchar(5))
insert into @table1 values
(3907,2457 ,'01/09/2013', 'CP'),
(3907,2896 ,'09/09/2013', 'CP'),
(3907,1866 ,'20/05/2013', 'S'),
(4040,3660 ,'10/05/2014', 'CP'),
(4040,3659 ,'15/05/2014', 'CP'),
(4040,1866 ,'20/05/2014', 'S')
<强>查询强>
SELECT person_id, event_id, event_date, event_type
FROM (
SELECT *
,ROW_NUMBER() OVER (
PARTITION BY person_id ORDER BY event_date DESC
) rownum
FROM @table1
WHERE event_type = 'CP'
) t
WHERE rownum = 1
<强>输出强>
person_id event_id event_date event_type
3907 2896 09/09/2013 CP
4040 3659 10/05/2014 CP
答案 3 :(得分:0)
与except语句的联合返回所有必需的行 - 甚至是在S的第一个实例之前和之后都具有CP实例的行。 我确信必须有一个比这更有效的解决方案,但时间和资源目前不是我的同伴!
select person_id,event_date,event_id,rn from
(select *,
row_number() over (partition by person_id order by event_date desc, event_id desc) rn
from (select *
from mytable t1
where not exists
(select 1 from mytable t2
where t2.event_type = 'S' AND
t2.person_id = t1.person_id AND
t2.event_date <= t1.event_date)
AND event_type = 'CP') t1) t1 where rn = 1
union
select person_id,event_date,event_id,rn from
(select *,
row_number() over (partition by person_id order by event_date desc, event_id desc) rn
from (select *
from mytable t1
where not exists
(select 1 from mytable t2
where t2.event_type = 'S' AND
t2.person_id = t1.person_id AND
t2.event_date <> t1.event_date)
AND event_type = 'CP') t1) t1 where rn = 1
except
select person_id,event_date,event_id,rn from
(select *,
row_number() over (partition by person_id order by event_date desc, event_id desc) rn
from (select *
from mytable t1
where not exists
(select 1 from mytable t2
where t2.event_type = 'S' AND
t2.person_id = t1.person_id AND
t2.event_date <= t1.event_date)
AND event_type = 'CP') t1) t1 where rn = 1