2012-07-20 4 views
5

ich die folgende Tabelle 2008 in SQL Server haben:SELECT DISTINCT mit LEFT JOIN, bestellt in T-SQL-BY

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) 

die IDs aller Datensätze des gleichen Typs, mit dem gleichen DTIN Datum auswählt, bestellt von Stout aufsteigend:

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 

Aber es gibt mir eine Fehlermeldung:

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

ich versuchte setzen, dass ORDER BY in d verschiedene Orte und alles scheint nicht zu funktionieren. Was mache ich hier falsch?

+5

Wie die Fehlermeldung deutlich sagt: Wenn Sie 'SELECT DISTINCT' verwenden, müssen die in der' ORDER BY'-Klausel angegebenen Spalten auch in der Liste der ausgewählten Spalten erscheinen - verwenden Sie also SELECT DISTINCT tbl.id , tbl.dtOut VON ..... ' –

+0

Oh. Aha. Also muss ich sie auch auswählen. Hmm ... interessante Anforderung ... aber, oh gut ... – ahmd0

Antwort

3

Wenn Sie es einzuengen einzelne IDs ab, erstellen Sie die Möglichkeit, dass jede ID möglicherweise mehr als ein DTOUT mit ihm verbunden ist. Wann wird Sql Server wissen, welche Bestellung verwendet wird?

Sie könnten versuchen:

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 

Aber, wie ich oben erwähnte dies die gleiche ID mehr aufgeführt zu haben als einmal die Möglichkeit öffnen kann, wenn es auf der rechten Seite Tabelle auf mehr als Datensatz übereinstimmt.

+0

It doesn Ihre Aussage produziert: Mehrdeutiger Spaltenname 'dtOut'. – ahmd0

+0

Behoben. Vergessen Sie den Tabellenalias in der order by-Klausel. –

+0

Auch hier ist das Problem, dass das, wonach Sie fragen, keine Bedeutung hat "Sagen Sie" gruppieren Sie diesen Obstkorb nach Typ (Äpfel, Orangen, usw.), beschränken Sie ihn auf nur einen einzigen von jedem Typ und sortieren Sie dann nach der Zeit, in der jede Frucht gepflückt wurde. "Im Kontext einer Datenbank, falls vorhanden Es gibt viele Äpfel im Korb, die alle zu verschiedenen Zeiten gepflückt wurden, es weiß nicht wirklich, welchen Wert man verwenden soll. " –

0

Sie können nur die Spalten in der ORDER BY-Klausel verwenden, die Teil Ihrer SELECT-Anweisung sind, wenn Sie das Schlüsselwort 'DISTINCT' verwenden. Sie können also nur nach tbl.id bestellen

Wenn IDs eindeutig sind, macht das Schlüsselwort DISTINCT keinen Sinn und führt zu Leistungseinbußen und Sie können es einfach entfernen. Falls dies nicht der Fall ist und Sie sich dafür entscheiden, auch tbl.dtOut zu wählen, während Sie DISTINCT beibehalten, kann Ihnen das Paar tbl.id und tbl.dtOut mehrere Einträge mit der gleichen tbl.id geben, was wahrscheinlich nicht erwünscht ist.

Überprüfen Sie this article für mögliche Problemumgehungen und Erklärung, warum solche Abfragen nicht zulässig sind.

0

Sie müssen die Spalte tbl.dtOut in Ihre Auswahlliste aufnehmen, damit sie weiß, worauf Sie bestellen müssen.

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

es funktioniert genau so, wie Sie es sagen. Vielen Dank. – ahmd0

6

Es ist nicht sinnvoll, ORDER nach einer Spalte zu sortieren, die nicht in der Liste der DISTINCT-Elemente enthalten ist.

Lassen Sie uns ein einfaches Szenario verwenden. Zuerst wird eine Tabelle FruitPerson:

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

Hier ist die Abfrage entspricht dem, was Sie zu tun versuchen:

SELECT DISTINCT Fruit 
FROM FruitPerson 
ORDER BY PersonName; 

Das Ergebnis dieser Abfrage ohne ORDER BY ist dies:

Fruit 
----- 
Apple 
Peach 

Aber jetzt ist die Frage: Wie sollte der Motor diese beiden Werte "Apple" und "Peach" von PersonName bestellen? Welche PersonNames? Es gibt zwei Leute pro Frucht! Welcher (n) Name (n) sollte genau verwendet werden, um zu entscheiden, ob Apple oder Peach zuerst kommt?

Stattdessen umschreiben Ihre Abfrage als ein Aggregat:

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

Danke für die Erklärung. Es macht Sinn, wie du es sagst ... Ich sollte zugeben, SQL ist nicht mein Fortay :) und ich bin jetzt mit einem anderen Problem fest :( – ahmd0

+0

Dies ist eine großartige Erklärung - danke für die Hilfe. –

0

Sie hatten diesen Fehler, weil Sie (tbl.dtOut) nicht in die Auswahlliste gestellt haben.

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 

Wollen Sie eine Ergebnismenge erhalten (mit 3 Zeilen) und wenn Sie die ID-Feld wollen auch dann

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 

(6 Reihen hat, wie es gibt die eindeutige Kombination aus id/Datum Feld)