Tsql 将具有一个DateTime列的行对合并为具有开始和结束日期列的单行
编辑:关于一个名称可以有多对不重叠的开始和结束这一事实,非常需要澄清。因此,合并对可以标识为“运行” 我猜这是一个重复的问题,但我似乎找不到另一个。如果有人能指给我看,那么这个可以被关闭或删除,或者别的什么 我有一张这样的桌子:Tsql 将具有一个DateTime列的行对合并为具有开始和结束日期列的单行,tsql,Tsql,编辑:关于一个名称可以有多对不重叠的开始和结束这一事实,非常需要澄清。因此,合并对可以标识为“运行” 我猜这是一个重复的问题,但我似乎找不到另一个。如果有人能指给我看,那么这个可以被关闭或删除,或者别的什么 我有一张这样的桌子: Id Name Action ActionDate ---- ------- ------ ---------- 1 John Start 01/15/2013 2 Mary Start
Id Name Action ActionDate
---- ------- ------ ----------
1 John Start 01/15/2013
2 Mary Start 01/17/2013
3 Nancy Start 01/17/2013
4 John End 01/18/2013
5 Mary End 01/18/2013
6 Nancy End 01/20/2013
7 John Start 01/19/2013
8 Mary Start 01/20/2013
9 Nancy Start 01/25/2013
10 John End 01/21/2013
11 Mary End 01/22/2013
12 Nancy End 01/30/2013
我需要一个使用基于集合的查询的结果集,如下所示:
Id Name Run StartActionDate EndActionDate
---- ------- ---- --------------- -------------
1 John 1 01/15/2013 01/18/2013
2 John 2 01/19/2013 01/21/2013
3 Mary 1 01/17/2013 01/18/2013
4 Mary 2 01/20/2013 01/22/2013
5 Nancy 1 01/17/2013 01/20/2013
6 Nancy 2 01/25/2013 01/30/2013
看看这个
select MIN(Id),Name,MIN(case Action when 'Start' then ActionDate End) as StartActionDate,MIN(case Action When 'End' then ActionDate End) as EndActiondate from dbo.Table group by Name
假设每个名称只有一条带“开始”的记录和一条带“结束”的记录,类似这样的方法应该可以工作:
SELECT T1.Id, T1.Name, T1.ActionDate AS [StartActionDate], T2.ActionDate AS [EndActionDate]
FROM MyTable T1
INNER JOIN MyTable T2 ON T1.Name = T2.Name
WHERE T1.Action = 'Start' AND T2.Action = 'End'
如果每个
名称都有多对名称,则不清楚要返回什么id
,但您应该能够使用类似row\u number()
的窗口函数为每个名称生成一个唯一的序列,然后生成最终结果:
;with cte as
(
select id, name, action, actiondate,
row_number() over(partition by name, action
order by actiondate) seq
from yourtable
)
select
min(id) id,
name,
max(case when action = 'start' then actiondate end) StartActionDate,
max(case when action = 'end' then actiondate end) EndActionDate
from cte
group by name, seq
order by id;
看
根据您的数据更改,您应该能够使用类似于:
;with cte as
(
select id, name, action, actiondate,
row_number() over(partition by name, action
order by actiondate) seq
from yourtable
)
select
row_number() over(order by name) id,
name,
seq run,
max(case when action = 'start' then actiondate end) StartActionDate,
max(case when action = 'end' then actiondate end) EndActionDate
from cte
group by name, seq
order by id
看。这就产生了一个结果:
| ID | NAME | RUN | STARTACTIONDATE | ENDACTIONDATE |
|----|-------|-----|--------------------------------|--------------------------------|
| 1 | John | 1 | January, 15 2013 00:00:00+0000 | January, 18 2013 00:00:00+0000 |
| 2 | John | 2 | January, 19 2013 00:00:00+0000 | January, 21 2013 00:00:00+0000 |
| 3 | Mary | 1 | January, 17 2013 00:00:00+0000 | January, 18 2013 00:00:00+0000 |
| 4 | Mary | 2 | January, 20 2013 00:00:00+0000 | January, 22 2013 00:00:00+0000 |
| 5 | Nancy | 1 | January, 17 2013 00:00:00+0000 | January, 20 2013 00:00:00+0000 |
| 6 | Nancy | 2 | January, 25 2013 00:00:00+0000 | January, 30 2013 00:00:00+0000 |
您的姓名是否有多对动作/日期?名称是否唯一?如果没有,结果将不可靠。是的,一个名称将有许多对开始和结束。是的,在结果集中,名称将是唯一的。@MarkBostleman如果名称将有许多对,那么您希望与每对关联的id是什么,带开始的id还是什么?谢谢Dan,我将更新问题,但每个名称不只有一个开始和结束日期。名称开始和结束多次。因此,您是要输出最小开始日期和最大结束日期,还是需要输出每个相邻的开始日期和结束日期对?在后一种情况下,什么是可能重叠的句点?相邻的句点对,而不是重叠的句点对。谢谢Anjali,我会更新这个问题,但每个名字不只有一个开始和结束日期。一个名字开始和结束很多次。