18 Stimmen

ORDER BY mit einer UNION von unterschiedlichen Datensätzen (T-SQL)

Ich habe eine Anfrage, die UNION zwei einigermaßen ähnliche Datensätze, die jedoch beide einige Spalten enthalten, die in dem anderen nicht vorhanden sind (d. h. die Spalten haben NULL-Werte in der resultierenden UNION .)

Das Problem ist, dass ich Folgendes tun muss ORDER die sich daraus ergebenden Daten unter Verwendung der Spalten, die nur in der einen oder der anderen Menge vorhanden sind, um die Daten in ein für die Software-Seite geeignetes Format zu bringen.

Zum Beispiel: Tabelle1 hat Felder ID, Cat, Price . Tabelle2 hat Felder ID, Name, Abbrv . El ID ist den beiden Tabellen gemeinsam.


Meine Abfrage sieht in etwa so aus:

SELECT t1.ID, t1.Cat, t1.Price, NULL as Name, NULL as Abbrv FROM t1 
UNION 
SELECT t2.ID, NULL as Cat, NULL as Price, t2.Name, t2.Abbrv FROM t2 
ORDER BY Price DESC, Abbrv ASC 

El ORDER BY ist der Punkt, an dem ich nicht weiterkomme. Die Daten sehen wie folgt aus:

100   Balls     1.53                       
200   Bubbles   1.24                       
100                     RedBall    101RB   
100                     BlueBall   102BB   
200                     RedWand    201RW   
200                     BlueWand   202BW   

...aber ich möchte, dass es so aussieht:

100   Balls     1.53                       
100                     RedBall    101RB   
100                     BlueBall   102BB   
200   Bubbles   1.24                       
200                     RedWand    201RW   
200                     BlueWand   202BW   

Ich hoffe, dass dies in T-SQL erledigt werden kann.

0 Stimmen

Verknüpfen die IDs Ihre T2-Produkte nicht mit dem T1-Produkt? Wenn nicht, woher wissen Sie dann, dass die RedWand und die BlueWand direkt nach Bubbles kommen?

0 Stimmen

Er sagt in der Frage: "Tabelle2 hat Felder ID (dieselbe wie in Tabelle1)"

0 Stimmen

Vielen Dank für die vielen Antworten; dies ist zwar erst meine erste Frage, aber die Gemeinschaft scheint schon jetzt großartig zu sein. Auch für diejenigen, die die "Architektur", die meine Frage impliziert, kritisieren würden - bitte beachten Sie, was ich oben und unten in der akzeptierten Antwort gesagt habe: Dies ist ein dummes Beispiel! Die "Tabellen" in meiner Frage stellen eigentlich zwei sehr komplexe SELECT-Abfragen dar, die mehrere Tabellen und Unterabfragen mit Aggregaten und berechneten Feldern umfassen. Nochmals vielen Dank!

31voto

JeffO Punkte 7827
Select ID, Cat, Price, Name, Abbrv
From
(SELECT t1.ID, t1.Cat, t1.Price, t1.Price AS SortPrice, NULL as Name, NULL as Abbrv 
FROM t1
UNION
SELECT t2.ID, NULL as Cat, NULL as Price, t1.Price as SortPrice, t2.Name, t2.Abbrv 
   FROM t2
   inner join t1 on t2.id = t1.id
) t3
ORDER BY SortPrice DESC, Abbrv ASC

Irgendwie muss man wissen, dass die Daten in Tabelle 2 mit Tabelle 1 verknüpft sind und den Preis teilen. Da die Null in abbrv an erster Stelle steht, ist es nicht erforderlich, eine SortAbbrv-Spalte zu erstellen.

4 Stimmen

Die Ausführung dieser Abfrage führt zu einem Syntaxfehler, es sei denn, die Unterabfrage hat einen Alias. Ich habe die Korrektur für Sie vorgenommen. +1

0 Stimmen

Richtig, so ist dies im Wesentlichen nur den Preis in der 2. Abfrage, so dass es mit sortiert werden kann. Diese würde wäre eine großartige Lösung, wenn die eigentliche Abfrage nicht schon so kompliziert wäre - sie hat Unterabfragen und aggregierte und berechnete Felder, von denen eines das primäre SORT-er ist (d. h. in diesem Fall der Preis). Ich müsste eigentlich die gesamte erste Abfrage für den JOIN im unteren Teil der UNION noch einmal duplizieren. Also +1 und akzeptiert, aber ich werde nicht mehr Zeit verschwenden, um zu versuchen, die reale Sache funktioniert so; es ist viel einfacher, die Daten in Code zu manipulieren, und wahrscheinlich sauberer.

3voto

Amy B Punkte 104656

Sie sollten UNION ALL anstelle von UNION verwenden, um die Kosten einer doppelten Prüfung zu sparen.

SELECT *
FROM
(
SELECT t1.ID, t1.Cat, t1.Price, NULL as Name, NULL as Abbrv FROM t1
UNION ALL
SELECT t2.ID, NULL as Cat, NULL as Price, t2.Name, t2.Abbrv FROM t2
) as sub
ORDER BY
  ID,
  CASE WHEN Price is not null THEN 1 ELSE 2 END,
  Price DESC,
  CASE WHEN Abbrv is not null THEN 1 ELSE 2 END,
  Abbrv ASC

0 Stimmen

Die eigentliche Abfrage, die ich arbeite, hat UNION ALL. Noch einmal, ID ist nicht die primäre ORDER-er, Preis ist. Die IDs können nicht für die Sortierung in der "realen" Abfrage verwendet werden, die ich bin auf der Grundlage dieser.

2voto

Avitus Punkte 15205

Eine schnelle Lösung wäre, 2 Einfügungen in eine temporäre Tabelle oder eine Tabellenvariable vorzunehmen, und als Teil der Einfügung in die temporäre Tabelle können Sie eine Flaggenspalte setzen, um die Sortierung zu erleichtern, und dann nach dieser Flaggenspalte ordnen.

0 Stimmen

Daran habe ich auch gedacht, aber ich habe versucht, es zu vermeiden. Trotzdem eine gute Antwort.

1voto

mundeep Punkte 2717

Aus der Spitze von meinem Kopf würde ich sagen, das Worst-Case-Szenario ist Sie erstellen eine temporäre Tabelle mit allen Feldern tun ein INSERT INTO die temporäre Tabelle aus T1 & T2 dann SELECT aus der temporären Tabelle mit einer Reihenfolge nach.

d.h.. Erstellen Sie eine temporäre Tabelle (z. B. #temp) mit den Feldern Id, Cat, Price, Name, Abbrv, und dann:

SELECT Id, Cat, Price, null, null INTO #temp FROM T1
SELECT Id, null, null, Name, Abbrv INTO #temp FROM T2
SELECT * FROM #temp ORDER BY Id, Price DESC, Abbrv ASC

NB: Ich bin mir nicht 100%ig sicher über die Null-Syntax der Einsätze, aber ich denke, es wird funktionieren.

EDIT: Bestellung nach Preis und Abkürzung nach der ID hinzugefügt... wenn die ID nicht T1 und T2 verbindet, was dann?

0 Stimmen

Ignorieren Sie die ID; der Preis ist der primäre Auftraggeber.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X