1

次のテーブルと行を検討してください。

リスト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'

行を列に変換したいので、入力イベントと出力イベントの 2 つの異なる列を作成できます。お気に入り:

リスト 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-nameが関連しているため、問題は行をフラットにする方法です。行を列に変換するには、通常、次のようなコードを作成します。

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 Ba​​nnister の両方のソリューションは、私が望んでいたことを実現します。最終的には 2 番目のものを選択しました。回答ありがとうございます。

4

3 に答える 3

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
于 2010-09-02T09:56:01.533 に答える
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

問題は、入出力セッションを何らかの方法でリンクする必要があるということです。このクエリでは、タイムスタンプイベント列を使用して実行しました。これがあなたが望んでいたものでない場合、あなたはより多くの情報を提供できますか?

更新:今、少し後処理するためにあなたがすることができます

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
于 2010-09-01T10:03:44.523 に答える
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
于 2010-09-01T06:38:29.343 に答える