Domanda:
creare una query che seleziona solo la stringa piu recente, in un record contenente stringhe duplicate? SQL?
anonymous
2013-10-10 01:10:58 UTC
ho creato una tabella esempio:

(from archivio)

id nome data

1 luca 01-02-2009

2 luca 10-05-2012

3 lino 15-07-2005

4 carlo 05-11-2006

5 lino 01-03-1999


il risultato che vorrei avere è il seguente:

1 luca 10-05-2012

3 lino 15-07-2005

4 carlo 05-11-2006


quindi come risultato finale , i nomi che si trovano unavolta sola (carlo) piu il nome con la data piu recente in caso di dupoduplicato (luca, lino)

grazie.
Quattro risposte:
?
2013-10-10 03:24:58 UTC
E quale id vuoi?



1) select min(id), nome, max(data) from archivio group by nome



Questa soluzione da il risultato che hai indicato, ma non sono sicuro che sia quello che effettivamente ti serve. Infatti l'id e la data nel caso di Luca appartengono a due record diversi.



2)

select archivio.*

from archivio

join (

select max(data), nome from archivio group by nome

) as T1 on T1.nome = archivio.nome and T1.data = archivio.data



In questo caso estraggo i record con la data più recente per ogni nome, ma se lo stesso nome è inserito due volte con la stessa data allora uscirà due volte. Ora si tratta di capire come eliminare questi duplicati. Quale record ti interessa? Uno qualsiasi? Il primo? L'ultimo?



3)

select min(T2.id), T2.nome, T2.data

from (

....select archivio.*

....from archivio

....join (

........select max(data), nome from archivio group by nome

....) as T1 on T1.nome = archivio.nome and T1.data = archivio.data

) as T2

group by T2.nome, T2.data



Questo elimina i duplicati lasciati dalla soluzione 2, selezionando il primo record trovato (supponendo che siano in ordine di id).



ps: la soluzione di FantaRed non funzionerà con tutti i db perché non tutti consentono di estrarre valori non aggregati che non appartengono al raggruppamento. In ogni caso non credo sia corretto usare quel sistema perché non si dà al dbms alcuna informazione su quale record selezionare. Può andare bene quando si sa per certo che i dati dipendono da un valore raggruppato (ad esempio quando si raggruppa per la chiave primaria o una chiave naturale) ma questo non è il caso.



EDIT2:

la query di Marcantonio è sbagliata perché fa due test di uguaglianza che non sono legati in alcun modo. Con un contenuto come questo:



1 Luca 10/10/12

2 Luca 10/10/12

3 Marco 01/10/12

4 Marco 10/10/12



verrebbe estratto:



1 Luca 10/10/12

2 Luca 10/10/12 perché Luca c'è nella prima subquery e 10/10/12 nella seconda.

3 Marco 01/10/12

4 Marco 10/10/12 perché Marco c'è nella prima subquery e 10/10/12 nella seconda.



In definitiva credo che la mia sia l'unica che funziona indipendentemente dal db.



@Fabrizio: "se è vero che per ogni nome le date sono tutte diverse"... non è specificato dall'autore della domanda. La tua query è equivalente alla mia seconda soluzione, salvo che io uso una join e tu una subquery. Il dbms probabilmente le eseguirà nello stesso modo quindi scegliere l'una o l'altra è solo una questione di gusti.
Tigrotto
2013-10-10 22:24:41 UTC
Quoto la query di Marcantonio che mi pare la + semplice (è meglio fare una query semplice, no ?) ma anche la + vicina alla soluzione. Ho notato in quella due cose che mi hanno indotto a rispondere:



 1) le subquery devono essere "fermate" sul nome, manca la clausola WHERE e così si può evitare il GROUP BY

 2) la data da selezionare deve essere = a quella determinata dalla subquery e non semplicemente un elemento "IN" di un insieme.



Da queste considerazioni, se è vero che per ogni nome le date sono tutte diverse, allora va bene questa SELECT qua



 SELECT

  A.Id, A.Nome, A.Data

 FROM

  [Tabella] A

 WHERE

  A.Data = (SELECT MAX(Data) FROM [Tabella] B WHERE B.Nome = A.Nome)

 ORDER BY

  A.Id



Puoi provarla subito ?, vedi che associa solo l'Id che corrisponde alla data maggiore come giustamente hai chiesto visto che hai capito che la soluzione proposta nei "Dettagli aggiuntivi" seleziona soltanto quello più piccolo ?
anonymous
2013-10-10 10:38:19 UTC
OK mi sembrava infatti allora per ottenere il risultato che vuoi mantenendo gli stessi ID della riga originale della tabella con la data più recente e anche nel caso che ci sia la stessa data in nomi diversi devi usare quest'altra:



SELECT * FROM [Tabella]

WHERE Data in (SELECT MAX(Data) FROM [Tabella] GROUP BY Nome)

AND Nome in (SELECT Nome FROM [Tabella] GROUP BY Nome)

ORDER BY Id



e il risultato sarà:



ID Nome Data

------------------------------------------

2 Luca 10/05/2012

3 Lino 15/07/2005

4 Carlo 05/11/2006



Con gli ID originali della riga in cui la Data è maggiore, la clausola ORDER BY finale è facoltativa se le righe sono state inserite in ordine di ID :)

L'unico problema potrebbe essere che se la tabella è molto grande l'elaborazione di questo statement potrebbe essere molto lunga :)))
FantaRed
2013-10-10 08:20:53 UTC
SELECT * FROM (

SELECT * FROM nome_della_tabella

ORDER BY data

) AS t GROUP BY nome


Questo contenuto è stato originariamente pubblicato su Y! Answers, un sito di domande e risposte chiuso nel 2021.
Loading...