2012-07-20 15 views
5

Ho la seguente tabella in SQL Server 2008:SELECT DISTINCT con LEFT JOIN, ordinate per in T-SQL

CREATE TABLE tbl (ID INT, dtIn DATETIME2, dtOut DATETIME2, Type INT) 

INSERT tbl VALUES 
(1, '05:00', '6:00', 1), 
(2, '05:00', '7:00', 1), 
(3, '05:01', '8:00', 1), 
(4, '05:00', '8:00', 1), 
(5, '05:00', '6:00', 2), 
(6, '05:00', '7:00', 2) 

che seleziona gli ID di tutti i record dello stesso tipo, con la stessa data dtIn, ordinata da Stout in ordine crescente:

SELECT DISTINCT tbl.id FROM tbl 
    LEFT JOIN tbl AS t1 
    ON tbl.type = t1.type AND 
    tbl.dtIn = t1.dtIn 
    ORDER BY tbl.dtOut ASC 

Ma mi dà un errore:

ORDER BY items must appear in the select list if SELECT DISTINCT is specified

ho provato a mettere che ORDER bY in d posti diversi e tutto ciò non sembra funzionare. Cosa sto facendo di sbagliato qui?

+5

Come dice chiaramente il messaggio di errore: se stai usando 'SELECT DISTINCT', allora le colonne specificate nella clausola' ORDER BY' devono apparire anche nella lista di colonne selezionate - quindi usa 'SELECT DISTINCT tbl.id , tbl.dtOut FROM ..... ' –

+0

Oh. Io vedo. Quindi devo selezionare anche loro. Hmm ... requisito interessante ... ma, oh beh ... – ahmd0

risposta

3

Quando si restringere verso il basso id individuali di, si crea la possibilità che ciascun ID potrebbe avere più di un dtOut ad esso associati. Quando ciò accade, in che modo Sql Server saprà quale ordine usare?

si potrebbe provare:

SELECT t1.id 
FROM tbl t1 
LEFT JOIN tbl t2 on t1.type = t2.type AND t1.dtIn = t2.dtIn 
GROUP BY t1.id, t2.dtOut 
ORDER BY t2.dtOut 

Tuttavia, come ho già detto questo può aprire la possibilità di avere lo stesso ID elencato più di una volta, se corrisponde a più di record sul tavolo destra.

+0

Non funziona sembra funzionare. La tua affermazione produce: Nome colonna ambiguo 'dtOut'. – ahmd0

+0

Risolto. Dimentica l'alias della tabella nella clausola order by. –

+0

Inoltre: ancora il problema qui è che in realtà quello che stai chiedendo non ha significato. "Stai dicendo" raggruppa questo cesto di frutta per tipo (mele, arance, ecc.), restringilo a un solo tipo di ogni tipo e poi ordina ogni volta che viene raccolto ogni frutto. "Nel contesto di un database, se ci sono molte mele nel cestino che sono state tutte raccolte in momenti diversi, non si sa davvero quale valore usare –

0

È possibile utilizzare solo le colonne nella clausola ORDER BY che fanno parte dell'istruzione select quando si utilizza la parola chiave "DISTINCT". Quindi puoi ordinare solo da tbl.id

Se gli ID sono univoci, la parola chiave DISTINCT non ha alcun senso e causerà un peggioramento delle prestazioni e puoi semplicemente rimuoverlo. Nel caso in cui non lo fossero e decidessi di selezionare tbl.dtOut anche mantenendo DISTINCT, la coppia tbl.id e tbl.dtOut possono darti più voci aventi lo stesso tbl.id che probabilmente non è desiderato.

Controllare this article per possibili soluzioni alternative e perché tali query sono proibite.

0

È necessario includere la colonna tbl.dtOut nell'elenco di selezione in modo che sappia su cosa ordinare.

SELECT DISTINCT tbl.id, tbl.dtOut FROM tbl 
    LEFT JOIN tbl AS t1 
    ON tbl.type = t1.type AND 
    tbl.dtIn = t1.dtIn 
    ORDER BY tbl.dtOut ASC 
+0

funziona proprio come lo metti tu. Grazie. – ahmd0

6

Non ha senso ordinare da una colonna che non è inclusa nell'elenco delle voci DISTINCT.

Utilizziamo uno scenario semplice. In primo luogo, una tabella FruitPerson:

Fruit PersonName 
----- ------ 
Apple Joe 
Apple Mary 
Peach Karen 
Peach Lance 

Ecco la query equivalente a quello che si sta cercando di fare:

SELECT DISTINCT Fruit 
FROM FruitPerson 
ORDER BY PersonName; 

Il risultato di questa query senza l'ORDER BY è questo:

Fruit 
----- 
Apple 
Peach 

Ma ora la domanda è: come dovrebbe il motore ordinare questi due valori "Apple" e "Peach" di PersonName? Which PersonNames? Ci sono due persone per frutto! Quale (i) nome (i), esattamente, dovrebbe usare per decidere se Apple o Peach viene prima?

Invece, riscrivere la query come un aggregato:

SELECT Fruit, MinName = Min(PersonName) -- which name to order on 
FROM FruitPerson 
GROUP BY Fruit -- here's how you get your distinctness 
ORDER BY MinName; 
+0

Grazie per aver spiegato questo. Ha senso il modo in cui lo metti ... Devo ammettere, SQL non è il mio massimo :) e io ora sono bloccato con un altro problema :( – ahmd0

+0

Questa è una grande spiegazione - grazie per l'aiuto. –

0

Si è verificato questo errore perché non è stato inserito (tbl.dtOut) nell'elenco di selezione.

SELECT DISTINCT tbl.dtOut FROM tbl  
    LEFT JOIN tbl AS t1 
    ON tbl.type = t1.type AND 
    tbl.dtIn = t1.dtIn 
    ORDER BY tbl.dtOut ASC 

otterrà un set di risultati (con 3 file) e se si desidera che il campo id troppo poi

SELECT DISTINCT tbl.dtOut, tbl.ID FROM tbl  
    LEFT JOIN tbl AS t1 
    ON tbl.type = t1.type AND 
    tbl.dtIn = t1.dtIn 
    ORDER BY tbl.dtOut ASC 

(avendo 6 righe, in quanto dà la distinta combinazione Off ID/data campo)