file Convertire a colonne che permettono duplicati
-
26-09-2019 - |
Domanda
Si consideri la seguente tabella e le righe:
Un elenco.
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'
Quello che voglio è quello di convertire i file in colonne, in modo da poter avere due colonne diverse, di eventi di ingresso e di uscita degli eventi. Come:
Elenco 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'
sono stato in grado di ottenere qualcosa di simile a seguente:
Elenco 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'
, ma il problema è come piatto le righe, in quanto la tuple duplicate ID-name sono rilevanti. Per convertire le righe in colonne di solito codice di qualcosa di simile:
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
, ma, naturalmente, il GROUP BY sta per lasciare fuori i duplicati, e questo è quello che non voglio.
Tutte le idee su come raggiungere questo obiettivo con una query?
Sarebbe bello avere una soluzione SQL portatile o per PostgreSQL, ma ogni idea è molto apprezzato.
EDIT: mi dispiace per la risposta tardiva. Entrambe le soluzioni da AlexRednic e Mark Bannister realizzare quello che volevo. Alla fine ho optato per il secondo, dal momento che sembra più chiaro per me. Grazie a tutti per le vostre risposte!
Soluzione
Prova il seguente:
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
Altri suggerimenti
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
Il fatto è che è necessario in qualche modo collegare le sessioni di input / output. In questa query ho fatto utilizzando la colonna evento timestamp. Potrebbe fornire ulteriori informazioni se questo non è quello che volevi?
Aggiornamento: ora, al post-processo un po 'si potrebbe fare
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
Sto scrivendo dal principio:
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'
- ecco la soluzione 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