考虑以下表格和行:
清单A.
ID, name, event, type
1, 'John Doe', '2010-09-01 15:00:00.000', 'input'
1, 'John Doe', '2010-09-03 11:00:00.000', 'input'
1, 'John Doe', '2010-09-04 17:00:00.000', 'input'
1, 'John Doe', '2010-09-02 15:00:00.000', 'output'
1, 'John Doe', '2010-09-03 16:00:00.000', 'output'
1, 'John Doe', '2010-09-06 17:00:00.000', 'output'
我想要的是将行转换为列,因此我可以有两个不同的列,输入事件和输出事件。像:
清单B。
ID, name, input event, output event
1, 'John Doe', '2010-09-01 15:00:00.000', '2010-09-02 15:00:00.000'
1, 'John Doe', '2010-09-03 11:00:00.000', '2010-09-03 16:00:00.000'
1, 'John Doe', '2010-09-04 17:00:00.000', '2010-09-06 17:00:00.000'
我能够获得如下内容:
清单C。
ID, name, input event, output event
1, 'John Doe', '2010-09-01 15:00:00.000', null
1, 'John Doe', '2010-09-03 11:00:00.000', null
1, 'John Doe', '2010-09-04 17:00:00.000', null
1, 'John Doe', null, '2010-09-02 15:00:00.000'
1, 'John Doe', null, '2010-09-03 16:00:00.000'
1, 'John Doe', null, '2010-09-06 17:00:00.000'
,但问题是如何平行行,因为重复的元组ID名称是相关的。要将行转换为列,我通常会编写如下代码:
select ID, name, max(case when type = 'input' then event else null end) as 'input event', max(case when type = 'output' then event else null end) as 'output event' from events group by ID, name
,但当然,GROUP BY将省略重复,这就是我不想要的。
如何通过查询实现这一目标?
有一个可移植的sql解决方案或postgresql会很好,但任何想法都非常感激。
编辑:对不起,迟到了。 AlexRednic和Mark Bannister的两个解决方案都实现了我的目标。我终于选择了第二个,因为它看起来更清晰。谢谢大家的回答!答案 0 :(得分:2)
尝试以下方法:
select ID, name, event as 'input event',
(select min(o.event)
from events o
where o.type = 'output' and
i.ID = o.ID and
i.name = o.name and
i.event < o.event) as 'output event'
from events i
where i.type = 'input'
group by ID, name, event
答案 1 :(得分:1)
select t1.id,t1.name,t1.event,t2.event from test t1
inner join test t2 on t1.event <= t2.event
and t1.type = 'input'
and t2.type = 'output'
and t1.id = t2.id
and t1.name = t2.name
事情是你需要以某种方式链接输入/输出会话。在此查询中,我使用timestamp事件列完成了该操作。如果这不是你想要的,你能提供更多信息吗?
更新:现在,您可以进行后期处理
with a as
(
select t1.id,t1.name,t1.event as in_event,t2.event as out_event from test t1
inner join test t2 on t1.event <= t2.event
and t1.type = 'input'
and t2.type = 'output'
and t1.id = t2.id
and t1.name = t2.name
)
select id,name,in_event,min(out_event)
from a
group by id,name,in_event
答案 2 :(得分:0)
我从一开始写作:
create table #a(
ID int,
name varchar(30),
event datetime,
type varchar(10)
)
insert #a
select
1, 'John Doe', '2010-09-01 15:00:00.000', 'input'
union select 1, 'John Doe', '2010-09-01 16:00:00.000', 'input'
union select 1, 'John Doe', '2010-09-01 17:00:00.000', 'input'
union select 1, 'John Doe', '2010-09-02 15:00:00.000', 'output'
union select 1, 'John Doe', '2010-09-02 16:00:00.000', 'output'
union select 1, 'John Doe', '2010-09-02 17:00:00.000', 'output'
- 这是解决方案sql
select
ID,
name,
case when type = 'input' then event else null end "input event",
case when type = 'output' then event else null end "output event"
from #a