Query Sql con o senza uso del Dinstinct.

giovedì 10 marzo 2011 - 17.46
Tag Elenco Tags  Oracle 9g

beppenike Profilo | Newbie

Salve a tutti, arrivo subito al dunque: una un tabella DIPENDENTI con i relativi campi: nome, cognome, matricola, ora_arrivo
quindi:

NOME COGNOME MATRICOLA ORA_ARRIVO
mario rossi 0010 23:30
francesco verdi 0020 12:23
carlo bianchi 0030 10:12
mario rossi 0010 11:30
carlo bianchi 0030 19:00
francesco verdi 0020 22:20
mario rossi 0010 23:35

Vorrei che mi ritornasse solo l'ultimo orario piu vicino a quello attuale per ogni dipendente, e quindi:

NOME COGNOME MATRICOLA ORA_ARRIVO
mario rossi 0010 23:35
francesco verdi 0020 22:20
carlo bianchi 0030 19:00

Qualche aiuto?
Grazie anticipatamente :)

alexmed Profilo | Guru

Ciao
Mha ... al volo mi sembra che basti un
SELECT DISTINCT (matricola) FROM dipendenti ORDER BY ora_arrivo DESC
alexmed

beppenike Profilo | Newbie

in questo caso però viene ordinata successivamente all'operazione di rimozione dei duplicati, quindi non mi prende l'ultimo orario utile del singolo dipendente.

ma_di Profilo | Junior Member

>Salve a tutti, arrivo subito al dunque: una un tabella DIPENDENTI
>con i relativi campi: nome, cognome, matricola, ora_arrivo
>quindi:
>
>NOME COGNOME MATRICOLA ORA_ARRIVO
>mario rossi 0010
>23:30
>francesco verdi 0020
>12:23
>carlo bianchi 0030
>10:12
>mario rossi 0010
>11:30
>carlo bianchi 0030
>19:00
>francesco verdi 0020
>22:20
>mario rossi 0010
>23:35
>
>Vorrei che mi ritornasse solo l'ultimo orario piu vicino a quello
>attuale per ogni dipendente, e quindi:
>
>NOME COGNOME MATRICOLA ORA_ARRIVO
>mario rossi 0010
>23:35
>francesco verdi 0020
>22:20
>carlo bianchi 0030
>19:00
>
>Qualche aiuto?
>Grazie anticipatamente :)

SELECT DISTINCT COGNOME, NOME,MATRICOLA,MAX(ORA_ARRIVO)
FROM DIPENDENTI
WHERE (COGNOME = 'rossi')
GROUP BY COGNOME,NOME,MATRICOLA

beppenike Profilo | Newbie

No, questo restituisce 1 record solo con associato l'orario piu vicino a quello attuale.
A me serve per ogni dipendente, tra i loro ingressi l'unico con data più vicina all'ora attuale:

Se mario rossi registra i suoi ingressi:

mario rossi 10:00
mario rossi 19:00
mario rossi 03:00

la query mi deve restituire SOLO "mario rossi 19:00"
se ci sono piu dipendenti d'evessere fatta la stessa cosa per ogni dipendente.

ma_di Profilo | Junior Member

Ciao,
ma il campo ORA_ARRIVO come è definito? ( datetime, int, nvarchar...)

beppenike Profilo | Newbie

TIME

alexmed Profilo | Guru

Ciao
Così dovrebbe andare

SELECT DISTINCT NOME, COGNOME, MATRICOLA, MAX(ORA_ARRIVO) AS arrivo
FROM DIPENDENTI
GROUP BY NOME, COGNOME, MATRICOLA

alexmed

alexmed Profilo | Guru

Premesso che non sono un esperto, ti consiglio di rivedere la struttura della tabella perchè non rispetta una delle tre regole di normalizzazione del database (http://it.wikipedia.org/wiki/Normalizzazione_del_database) in quanto nella tabella vengono ripetuti NOME COGNOME e MATRICOLA e quindi sarebbe da sdoppiare:

Tabella DIPENDENTI

MatricolaID - Nome - Cognome

Tabella ORARI

OrarioID - MatricolaID - Ora_di_arrivo

Se decidi di rivedere in questo modo la struttura la query di prima diventerebbe:

SELECT DISTINCT DIPENDENTI.MatricolaID, DIPENDENTI.NOME, DIPENDENTI.COGNOME, MAX(ORARI.Ora_di_arrivo) AS ORARIO
FROM DIPENDENTI INNER JOIN
ORARI ON DIPENDENTI.MatricolaID = ORARI.MatricolaID
GROUP BY DIPENDENTI.MatricolaID, DIPENDENTI.NOME, DIPENDENTI.COGNOME

Ciao

alexmed

>EDIT: Mi sono accorto ora che stai lavorando in Oracle, quindi non ti garantisco il risultato perchè Oracle non lo mai visto. Io uso SQL Server 2008 Express.

lbenaglia Profilo | Guru

>Vorrei che mi ritornasse solo l'ultimo orario piu vicino a quello
>attuale per ogni dipendente, e quindi:
>
>NOME COGNOME MATRICOLA ORA_ARRIVO
>mario rossi 0010
>23:35
>francesco verdi 0020
>22:20
>carlo bianchi 0030
>19:00
>
>Qualche aiuto?

Ciao Giuseppe,

Ti allego un paio di esempi realizzati con SQL Server 2008 che dovrebbero essere compatibili con la tua versione di Oracle (non so se sono presenti le CTE nella 9i):

USE tempdb; CREATE TABLE dbo.foo( Nome varchar(10) NOT NULL, Cognome varchar(10) NOT NULL, Matricola char(4) NOT NULL, OraArrivo time(0) NOT NULL ); INSERT dbo.foo VALUES ('mario', 'rossi', '0010', '23:30') , ('francesco', 'verdi', '0020', '12:23') , ('carlo', 'bianchi', '0030', '10:12') , ('mario', 'rossi', '0010', '11:30') , ('carlo', 'bianchi', '0030', '19:00') , ('francesco', 'verdi', '0020', '22:20') , ('mario', 'rossi', '0010', '23:35'); /* Soluzione 1: utilizzo una Common Table Expression */ WITH CTE_GetKey(Matricola, OraArrivo) AS ( SELECT Matricola, MAX(OraArrivo) FROM dbo.foo GROUP BY Matricola ) SELECT F.* FROM dbo.foo AS F JOIN CTE_GetKey AS K ON F.Matricola = K.Matricola AND F.OraArrivo = K.OraArrivo; /* Soluzione 2: utilizzo la classica tabella derivata */ SELECT F.* FROM dbo.foo AS F JOIN ( SELECT Matricola, MAX(OraArrivo) AS OraArrivo FROM dbo.foo GROUP BY Matricola ) AS K ON F.Matricola = K.Matricola AND F.OraArrivo = K.OraArrivo; /* Output: Nome Cognome Matricola OraArrivo ---------- ---------- --------- ---------------- carlo bianchi 0030 19:00:00 francesco verdi 0020 22:20:00 mario rossi 0010 23:35:00 (3 row(s) affected) */ DROP TABLE dbo.foo;

>Grazie anticipatamente :)
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/

beppenike Profilo | Newbie

Eccellente!!!!
Grazie :D
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5