2016-01-22 7 views
7

Ho una tabella di dati di accesso che assomiglia a questo:selezionare il gruppo stessa colonna in base alla data in diverse colonna

Created    | Action 
20/01/2016 08:00:00 AM login 
20/01/2016 10:05:10 AM logout 
20/01/2016 12:00:00 PM login 
20/01/2016 04:12:22 PM logout 
21/01/2016 08:00:50 AM login 
21/01/2016 09:44:42 AM login 
21/01/2016 10:44:42 AM login 
21/01/2016 04:00:42 PM logout 

ho bisogno di selezionare un set di risultati che assomiglia a questo:

Created  | Login | Logout   
20/01/2016  08:00:00 AM 04:12:22 PM 
21/01/2016  08:00:50 PM 04:00:42 PM 

Qui è quello che ho provato:

SELECT 
    CONVERT(VARCHAR(10),li.Created,10) [Date], 
    CONVERT(VARCHAR(8),MAX(li.Created),8) [Login], 
    CONVERT(VARCHAR(8),MAX(lo.Created),8) [Logout] 
FROM Logins li 
LEFT JOIN Logins lo ON lo.[Action] = 'logout' 
GROUP BY li.Created 

Ma il risultato non è raggruppato per data.

Qual è il modo corretto?

+2

Provare 'gruppo per CONVERT (VARCHAR (10), li.Created, 10)' invece. – jpw

+1

Come sapresti che 04:12:22 AM per qualche motivo arriverà _after_ 08:00:00 AM lo stesso giorno ...? Qual è la regola che dice a che ora scegliere? –

+0

@JoachimIsaksson Era un errore di battitura, l'ho corretto – Smith

risposta

1

Simile alla risposta di Rahul, ma è possibile effettuare un auto join per ottenere il primo accesso/ultimo logout e solo raggruppare entro la data per ottenere il risultato richiesto;

SELECT CONVERT(DATE,  li.created) [Date], 
     CONVERT(TIME, MIN(li.created)) [Login], 
     CONVERT(TIME, MAX(lo.created)) [Logout] 
FROM Logins li 
JOIN Logins lo 
    ON CONVERT(DATE, li.created) = CONVERT(DATE, lo.created) 
AND li.action = 'login' 
AND lo.action = 'logout' 
GROUP BY CONVERT(DATE, li.created) 

An SQLfiddle to test with.

MODIFICA: non testata per SQL Server 2005, potrebbe essere necessario impostare una lunghezza per i varchars;

SELECT CONVERT(VARCHAR, li.created, 110) [Date], 
     CONVERT(VARCHAR, MAX(li.created), 8) [Login], 
     CONVERT(VARCHAR, MAX(lo.created), 8) [Logout] 
FROM Logins li 
JOIN Logins lo 
    ON CONVERT(VARCHAR, li.created, 110) = CONVERT(VARCHAR, lo.created, 110) 
AND li.action = 'login' 
AND lo.action = 'logout' 
GROUP BY CONVERT(VARCHAR, li.created, 110) 

Another SQLfiddle.

+0

Questa conversione non funziona in sql server 2005 – Smith

+0

@Smith Hai taggato con SQL Server 2008, quindi l'ho provato con quello. Forse dovresti ridigitare la domanda se hai bisogno di SQL Server 2005. –

+0

Ora voglio unire i nomi dei dipendenti dalla tabella dei dipendenti, devo fare un'altra domanda o aggiungerla a questa? – Smith

3

Si può provare in questo modo:

SELECT 
CONVERT(VARCHAR(10),li.Created,10) [Date], 
CONVERT(VARCHAR(8),MAX(li.Created),8) [Login], 
CONVERT(VARCHAR(8),MAX(lo.Created),8) [Logout] 
From Logins li 
Left Join Logins lo on lo.[Action] = 'logout' 
GROUP BY CAST(li.Created AS DATE) 

cioè, è necessario eseguire il raggruppamento i record della data e non per data e ora entrambi.

+0

Penso che otterrei il login 04:12:22 logout 10: 05.10AM ...? –

+0

@JoachimIsaksson Era un errore di battitura, l'ho corretto – Smith

+0

@Rahul Tripathi sto ottenendo lo stesso tempo di logout per tutti i risultati – Smith

2

Suppongo che il logout delle 4:00 del 20 nei risultati sia una svista, altrimenti avremmo bisogno di conoscere la logica che determina che dovrebbe essere considerata l'ora di uscita per quel giorno.

Un problema è che si sta tentando di visualizzare solo le date come gruppi, ma si sta raggruppando per data e ora.

Prova a modificare:

SELECT 
    CAST(LI.created AS DATE) AS created, 
    MIN(CAST(LI.created AS TIME)) AS login, 
    MAX(CAST(LO.created AS TIME)) AS logout 
FROM 
    dbo.My_Table LI 
LEFT OUTER JOIN dbo.My_Table LO ON 
    LO.action = 'logout' AND 
    CAST(LO.created AS DATE) = CAST(LI.created AS DATE) 
WHERE 
    LI.action = 'login' 
GROUP BY 
    CAST(LI.created AS DATE) 

Un'altra cosa da considerare è se il login periodi possono estendersi data confini. Se questo è nel settore tecnologico, non sarebbe strano avere un login di 1/20 10pm e un logout di 1/21 2am. ;)

+0

Sto ottenendo anche lo stesso tempo di logout per tutti i risultati – Smith

+0

Ho aggiunto una condizione 'JOIN' basata anche alla data, che ritengo dovrebbe correggere quel problema. Non c'è tempo per testarlo adesso, ma spero che questo faccia il trucco. –