"Unterabfrage hat mehr als 1 Wert" für das SELECT-Unterabfrage
Ich bin mit dem MS SQL Server Management Studio 2008. Ich habe ein Problem mit dem schreiben einer Unterabfrage. Dies ist die komplette Abfrage wie folgt:
SELECT DISTINCT
FH.ShipDate, AVG(FH.[Dist Freight]) AS [Atlantic Freight Charge],
(SELECT DISTINCT [Non-Atlantic Freight Charge]
FROM
(SELECT DISTINCT
FH.ShipDate, AVG(FH.[Dist Freight]) AS [Non-Atlantic Freight Charge]
FROM dbo.vw_FreightHistory AS FH
WHERE VendorName != 'Atlantic Trucking'
GROUP BY ShipDate, VendorName) AS [Non-Atlantic Freight Charge])
FROM dbo.vw_FreightHistory as FH
WHERE VendorName = 'Atlantic Trucking'
GROUP BY ShipDate, VendorName
ORDER BY ShipDate
Dem Thema erste kam, als ich Hinzugefügt, dass die zweite Unterabfrage. Die erste Unterabfrage kam nicht wieder irgendwelche Fehler, aber es zeigte die gesamte Durchschnittliche Summe von "Dist " Fracht" in jedem ShipDate record eher als der Durchschnitt für nur ShipDate. Ich schrieb die zweite Unterabfrage zu versuchen und zu beheben, aber jetzt bin ich immer diese Fehlermeldung:
Msg 512, Ebene 16, Status 1, Zeile 1
Unterabfrage hat mehr als 1 Wert. Dies ist nicht zulässig, wenn die Unterabfrage folgt =, !=, <, <= , >, >= oder wenn die Unterabfrage als Ausdruck verwendet.
Bitte lassen Sie mich wissen, wenn ich etwas verdeutlichen.
Nicht im Zusammenhang mit deiner Fehlermeldung, aber Sie zu sein scheinen, fehlt eine schließende Klammer.
Klammern sind in Ordnung, nichts fehlt
[Nicht-Atlantic Frachtkosten] return einige Ergebnisse. Sie haben gebaut, das Durchschnittliche pro-date, so dass, wenn Sie extrahieren Durchschnitt für heute und für morgen, Ihre DISTINCT [Non-Atlantic Frachtkosten] liefert 2 Ergebnisse.
es ist eine ziemlich große Tabelle, aber die Attribute, die ich versuche zu verwenden sind ShipDate, VendorName, und Dist Fracht. Im Grunde, was ich versuche zu tun, ist zeigen, ein trend der Durchschnitt "Dist Fracht -" Kosten für eine bestimmte VendorName und dann der Durchschnitt für alle anderen Anbieter, die in einer anderen Spalte. Die Ausgabe soll drei Spalten: jede einzelne ShipDate, die durchschnittlichen Frachtkosten für die Anbieter Ein an diesem Tag, und die durchschnittlichen Frachtkosten für alle anderen Anbieter.
InformationsquelleAutor Martin | 2013-07-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich denke, was du willst, ist so etwas wie dieses:
Dies scheint zu funktionieren wunderbar. Ich wusste nicht, könnten Sie Fälle, in SQL (ich bin ein hübsches basic user), das ist wirklich ordentlich. Sieht aus wie es nur geht durch und greift die Durchschnittliche Dist Fracht, wenn der name Atlantic LKW, und wenn es nicht in den Datensatz für diesen Tag, dann wird Null zurückgegeben. Dann tut das gleiche für alle anderen Träger. Vielen, vielen Dank!! Übrigens, haben Sie irgendwelche Empfehlungen für websites, unterrichten diese differenziertere Abfragen?
In diesem bestimmten Beispiel kam von den Jahren des Schreibens Finanzberichten und Suche im code. Für fortgeschrittene sql-Konzepte und-Abfragen, wie ich diese Ressource hier, obwohl es nicht unbedingt in Ihrem Fall anwendbar: sommarskog.se
Hah, wieder gut ich Schätze die Eingabe. Ich werde überprüfen, dass die website aus.
Ah, schön zu sehen, jemand hatte die gleiche Antwort ich zu mir kam, und eher lapidar. Martin, ich hoffe, dass meine Antwort zumindest dient als Erklärung, warum deine Abfrage Probleme hatte.
InformationsquelleAutor Petio Ivanov
Das problem ist, Sie haben eine Unterabfrage zurückgeben mehrerer Zeilen und Sie versuchen, speichern Sie es als einen Wert in eine einzelne Zeile/Spalte-Kombination.
Zu verstehen, warum dies der Fall ist, schauen wir uns an, wie das Ergebnis Aussehen würde, wie für die äußere Abfrage, die 'Atlantic Freight Charge':
Tabelle 1 - Atlantischen Frachtkosten
Und schauen was die innere Unterabfrage zurückgeben könnte:
Tabelle 2 - Nicht-Atlantic Frachtkosten
Schließlich, was machen die distinct -
Non-Atlantic Freight Charge
Zeilen, die Aussehen wie für Tabelle 2?Tabelle 3 - Verschiedene Nicht-Atlantic Frachtkosten
Nun, in SQL, werden Sie angeben, dass Sie möchten, dass ein Bericht mit drei Spalten, basierend auf der SELECT-Klausel. Hier ist, wie die, die aus legt:
Sie sehen, die erste Spalte ist
ShipDate
, die zweite Spalte istAtlantic Freight Charge
, und die Dritte Spalte eine Abfrage jeder getrenntenNon-Atlantic Freight Charge
aus einer inneren Unterabfrage.In, um SQL Server zu stellen das richtig, vorstellen zu versuchen, um die Ergebnisse der Abfrage in der ersten Tabelle.
Also für die erste Zeile von Tabelle 1:
Brauchen wir, um eine Spalte hinzuzufügen
Non-Atlantic Freight Charge
, und wir speichern es die Ergebnisse der Abfrage aus der Tabelle 3:Uh oh. Wir haben eine Tabelle, innen unserem Tisch.
Ist das problem, wir haben eine Tabelle innerhalb einer anderen Tabelle!
So gibt es zwei Lösungen für Ihr problem. Sollten Sie beurteilen die Leistung der einzelnen.
Die erste ist die Verwendung einer Funktion namens Common Table Expressions oder CTEs, um zwei separate Abfragen und verbinden die Ergebnisse.
Dieser Abfrage würde wie folgt Aussehen:
CTE-Lösung
Gibt es einige änderungen, die ich gemacht, die ich darauf hinweisen zu müssen:
ORDER BY
ist eigentlich verboten in common table expressions sowieso so, dass ich hätte zu bewegen, die Klausel zu Ende.FULL OUTER JOIN
um Sie zu verbinden, so dass jede Zeile, die fehlt in einem noch angezeigt, aber er erscheint mit einer null. Stellen Sie sicher, dass dies ist, was Sie wollen.COALESCE
um sicherzustellen, dass im Falle es ist ein Tag ohneAtlantic Freight Charge
s und somit gibt es keine ShipDate für den jeweiligen Tag in derAtlantic
CTE, dann wird es mit dem Datum aus derNonAtlantic
CTE.Die Art und Weise dies funktioniert, ist, dass es verbindet die beiden Anfragen wie diese:
Und so die
COALESCE
undISNULL
erlauben, mich zu verwandeln, in einen einzigen Satz von Daten wie diese:Jedoch, dass wahrscheinlich nicht die beste Performance-Lösung
Es ist am einfachsten zu implementieren, nehmen Sie Ihre zwei Abfragen, führen Sie beide, und treten Sie die Ergebnisse. Aber der SQL-Server unterstützt die Aggregat-Funktionen, mit denen Sie die partition, die Ergebnisse. Sie können daran interessiert sein, den Blick in die Semantik der OVER-Klausel, um zu lernen mehr über, wie Sie Ihren Bericht in nur einer einzigen Abfrage. Ich habe umgesetzt Abfragen wie mich, aber in der Regel mit
SUM
s, nichtAVG
s. Ich würde eine mögliche Implementierung einer Lösung, mit der OVER-Klausel verwendet, aber es könnte ein wenig kompliziert und ich würde mir sorgen machen, dass ich Durcheinander Mittelung der Ergebnisse korrekt. Eigentlich jetzt, dass ich daran denke, so etwas kann funktionieren:Aber ich vergesse, wenn AVG zählt null-Zeilen oder nicht.
Ich hoffe jedenfalls, ich habe sowohl Ihre Frage beantwortet und Ihnen geholfen zu verstehen, warum Ihre Abfrage ein problem hatte.
Gut verdammt, ich hatte nicht erwartet, eine so ausführliche Antwort wie die deine. Danke für das brechen es unten, Stück für Stück und zeigen mir genau, warum es nicht funktioniert, als auch mit diesen beiden Lösungen. Ich landete mit dem Fall zu Petio eingereicht. Ich war mir nicht bewusst, das "VERSCHMELZEN" - Klausel, das ist wirklich raffiniert und nützlich. Sehr geschätzt!
Vielen Dank, Martin! Während ich hasse es zu verkaufen, meine Bescheidenheit, die für den Ruf auf der Website, es wäre schön, wenn Sie meine Lösung ein upvote/plus one/was auch immer Sie nennen es nur um zu zeigen, dass Sie es nützlich gefunden. Petio die Lösung mehr als ausreichend für Ihre Bedürfnisse, und ich hoffe, dass die Leute, die diesen Beitrag finden, der sowohl für seine Antwort und meine hilfreich.
Leider habe ich nicht genug rep upvote Sie, aber ich werde auf jeden Fall kommen Sie zurück zu diesem post, wenn ich kann. Nochmals vielen Dank.
Oh, wusste gar nicht, dass man den Ruf zu upvote. Naja, ich hoffe, Sie genießen die StackOverflow-Gemeinschaft. 🙂
InformationsquelleAutor Aaron Friel
Es hängt davon ab, was Sie erwarten, um zu erscheinen, in der einzelne Spalte, wenn Sie mehr als eine Zeile zurückgegeben wird?
Wenn Sie möchten, dass die insgesamt von Kosten, nutzen
SUM()
rund um Ihre multiple-row-Rückkehr Unterabfrage:InformationsquelleAutor Bohemian