2008-11-05 10 views
48

ich die Spalten in der Auswahlliste in der Reihenfolge von Liste hinzugefügt, aber es immer noch gibt mir den Fehler:ORDER BY-Elemente müssen in der Auswahlliste angezeigt werden, wenn SELECT DISTINCT angegeben

ORDER BY-Elemente in erscheinen müssen die Auswahlliste, wenn SELECT DISTINCT angegeben ist. Hier

ist die gespeicherte Prozedur:

CREATE PROCEDURE [dbo].[GetRadioServiceCodesINGroup] 
@RadioServiceGroup nvarchar(1000) = NULL 
AS 
BEGIN 
SET NOCOUNT ON; 

SELECT DISTINCT rsc.RadioServiceCodeId, 
       rsc.RadioServiceCode + ' - ' + rsc.RadioService as RadioService 
FROM sbi_l_radioservicecodes rsc 
INNER JOIN sbi_l_radioservicecodegroups rscg 
ON rsc.radioservicecodeid = rscg.radioservicecodeid 
WHERE rscg.radioservicegroupid IN 
(select val from dbo.fnParseArray(@RadioServiceGroup,',')) 
OR @RadioServiceGroup IS NULL 
ORDER BY rsc.RadioServiceCode,rsc.RadioServiceCodeId,rsc.RadioService 

END 

Antwort

52

Try this:

ORDER BY 1, 2 

ODER

ORDER BY rsc.RadioServiceCodeId, rsc.RadioServiceCode + ' - ' + rsc.RadioService 
+8

Wahrscheinlich eine gute Idee, um das Warum von diesem zu erweitern - insbesondere die Tatsache, dass die Spalten nicht eindeutig identifiziert werden, wenn sie in einem berechneten Feld verwendet werden. –

+3

Neugierig, was die SNYtax ORDER BY 1, 2 tut. – Xaisoft

+0

Bestellung von 1, 2 arbeitete für mich in SQL Server. 1,2,3, ... sind im Grunde 1 basierte Indizes der Spalten, die in der SELECT [1,2,3] -Anweisung verwendet werden. Das habe ich bekommen. –

41

Während sie nicht dasselbe sind, in einem gewissen Sinne DISTINCT impliziert eine GROUP BY, denn jeder DISTINCT neu geschrieben werden konnte GROUP mit BY statt. Vor diesem Hintergrund macht es keinen Sinn, nach etwas zu ordnen, das nicht in der Gesamtgruppe liegt.

Zum Beispiel, wenn Sie eine Tabelle wie folgt aus:

 
col1 col2 
---- ---- 
1  1 
1  2 
2  1 
2  2 
2  3 
3  1 

und dann versuchen, es so zu fragen:

SELECT DISTINCT col1 FROM [table] WHERE col2 > 2 ORDER BY col1, col2 

, die keinen Sinn machen würde, weil es konnte Ende up mehrere col2 Werte pro Zeile sein. Welchen sollte es für die Bestellung verwenden? Natürlich wissen Sie in dieser Abfrage, dass die Ergebnisse nicht so sein würden, aber der Datenbankserver kann das nicht im Voraus wissen.

Jetzt ist Ihr Fall ein wenig anders. Sie haben alle Spalten aus der order by-Klausel in der select-Klausel eingefügt, und daher scheint es auf den ersten Blick so, als ob sie alle gruppiert wären. Einige dieser Spalten wurden jedoch in ein berechnetes Feld eingeschlossen. Wenn Sie dies in Kombination mit distinct tun, kann die distinct Direktive nur auf die Endergebnisse der Berechnung angewendet werden: Es weiß nichts über die Quelle der Berechnung mehr.

Das bedeutet, dass der Server nicht wirklich weiß, dass er auf diese Spalten zählen kann. Es weiß, dass sie verwendet wurden, aber es weiß nicht, ob die Berechnungsoperation einen ähnlichen Effekt wie in meinem ersten einfachen Beispiel verursachen könnte.

Jetzt müssen Sie etwas anderes tun, um dem Server mitzuteilen, dass die Spalten für die Bestellung in Ordnung sind.Es gibt mehrere Möglichkeiten, das zu tun, aber dieser Ansatz sollte in Ordnung arbeiten:

SELECT rsc.RadioServiceCodeId, 
      rsc.RadioServiceCode + ' - ' + rsc.RadioService as RadioService 
FROM sbi_l_radioservicecodes rsc 
INNER JOIN sbi_l_radioservicecodegroups rscg 
    ON rsc.radioservicecodeid = rscg.radioservicecodeid 
WHERE rscg.radioservicegroupid IN 
    (SELECT val FROM dbo.fnParseArray(@RadioServiceGroup,',')) 
    OR @RadioServiceGroup IS NULL 
GROUP BY rsc.RadioServiceCode,rsc.RadioServiceCodeId,rsc.RadioService 
ORDER BY rsc.RadioServiceCode,rsc.RadioServiceCodeId,rsc.RadioService 
+0

Wenn möglich, können Sie ein wenig mehr auf diese? – Xaisoft

+1

Sicher - aktualisiert die Post. –

+0

Distinct bedeutet nur, die Duplikate zu eliminieren, und wenn Sie das getan haben, macht es Sinn, die einzelnen Zeilen im Ergebnis zu ordnen. –

9

einer von diesen Versuchen:

  1. Verwenden Sie den Spaltenalias:

    ORDER BY RadioServiceCodeId, Radioservice

  2. Verwenden Spaltenposition:

    ORDER BY 1,2

Sie können nur um durch Spalten, die im Ergebnis der DISTINCT-Abfrage erscheinen tatsächlich - Die zugrunde liegenden Daten sind nicht zur Bestellung verfügbar.

2

Eindeutig und Gruppieren Im Allgemeinen tun die gleichen Dinge für verschiedene Zwecke ... Sie erstellen beide eine Arbeitsspeicher-Tabelle basierend auf den gruppierten Spalten (oder ausgewählt in der Select Distinct-Klausel). und füllen Sie dann diese Arbeitstabelle, während die Abfrage liest Daten, Hinzufügen einer neuen "Zeile" nur, wenn die Werte zeigen, dass dies erforderlich ist ...

Der einzige Unterschied ist, dass in der Gruppe von gibt es zusätzliche "Spalten" B. Sum(), Count(), Avg(), usw., die für jede gelesene Originalzeile aktualisiert werden müssen, dies muss Distinct nicht tun ... Im Spezialfall wo Sie gruppieren Nur um eindeutige Werte zu erhalten (Und es gibt keine Aggregatspalten in der Ausgabe), dann ist es wahrscheinlich genau das gleiche Quer y plan ... Es wäre interessant, den Abfrageausführungsplan für die zwei Optionen zu überprüfen und zu sehen, was es getan hat ...

Bestimmt ist der Weg zur Lesbarkeit, wenn Sie das tun (Wenn Ihr Ziel ist es doppelte Zeilen zu beseitigen, und Sie sind der Berechnung keine aggregierten Spalten)

2

wenn Sie definieren Verkettung benötigen Sie einen ALIAS für die neue Spalte verwenden, wenn Sie auf es mit DISTINCT Einige Ex kombiniert bestellen möchten mit sql 2008

--this works 

    SELECT DISTINCT (c.FirstName + ' ' + c.LastName) as FullName 
    from SalesLT.Customer c 
    order by FullName 

--this works too 

    SELECT DISTINCT (c.FirstName + ' ' + c.LastName) 
    from SalesLT.Customer c 
    order by 1 

-- this doesn't 

    SELECT DISTINCT (c.FirstName + ' ' + c.LastName) as FullName 
    from SalesLT.Customer c 
    order by c.FirstName, c.LastName 

-- the problem the DISTINCT needs an order on the new concatenated column, here I order on the singular column 
-- this works 

    SELECT DISTINCT (c.FirstName + ' ' + c.LastName) 
     as FullName, CustomerID 
     from SalesLT.Customer c 

order by 1, CustomerID 

-- this doesn't 

    SELECT DISTINCT (c.FirstName + ' ' + c.LastName) as FullName 
    from SalesLT.Customer c 
     order by 1, CustomerID 
0

Sie könnten versuchen, eine Subq Sehr gut:

SELECT DISTINCT TEST.* FROM (
    SELECT rsc.RadioServiceCodeId, 
     rsc.RadioServiceCode + ' - ' + rsc.RadioService as RadioService 
    FROM sbi_l_radioservicecodes rsc 
     INNER JOIN sbi_l_radioservicecodegroups rscg ON rsc.radioservicecodeid = rscg.radioservicecodeid 
    WHERE rscg.radioservicegroupid IN 
     (select val from dbo.fnParseArray(@RadioServiceGroup,',')) 
     OR @RadioServiceGroup IS NULL 
    ORDER BY rsc.RadioServiceCode,rsc.RadioServiceCodeId,rsc.RadioService 
) as TEST 
Verwandte Themen