Zwei Selects in einem Select berechnen und verrechnen
Wieso funktioniert folgender Select nicht? Es kann nur eine Kleinigkeit sein... Danke!
select eins / zwei
from
(select count(*) as eins from tabelle where 'Kanten SOLL' = 'Kanten IST' and 'Kanten SOLL' between '29.07.2013' and '02.08.2013'),
(select count(*) as zwei from tabelle where 'Kanten SOLL' between '29.07.2013' and '02.08.2013');
Fehlertext:
Meldung 102, Ebene 15, Status 1, Zeile 6
Falsche Syntax in der Nähe von ','.
(Microsoft SQL)
select eins / zwei
from
(select count(*) as eins from tabelle where 'Kanten SOLL' = 'Kanten IST' and 'Kanten SOLL' between '29.07.2013' and '02.08.2013'),
(select count(*) as zwei from tabelle where 'Kanten SOLL' between '29.07.2013' and '02.08.2013');
Fehlertext:
Meldung 102, Ebene 15, Status 1, Zeile 6
Falsche Syntax in der Nähe von ','.
(Microsoft SQL)
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 214137
Url: https://administrator.de/contentid/214137
Ausgedruckt am: 26.11.2024 um 08:11 Uhr
15 Kommentare
Neuester Kommentar
Abgesehen davon, daß ich bei Spaltennamen mit Leerzeichen graue Haare bekomme und der SQL Server ein Datum vermutlich in einem anderen Format haben will, fangen wir doch mal mit den Grundlagen der Fehlersuche an:
Wenn ein verknüpftes Statement nicht tut, verifiziert man zuerst einmal, ob die zugrundeliegenden Statements funktionieren.
D.h. funktionieren die Selects einzeln? Und tun Sie das, was sie sollen?
select count(*) as eins from tabelle where 'Kanten SOLL' = 'Kanten IST' and 'Kanten SOLL' between '29.07.2013' and '02.08.2013'
und
select count(*) as zwei from tabelle where 'Kanten SOLL' between '29.07.2013' and '02.08.2013'
Und wenn Sie nicht tun, vereinfacht man das Statement, um zu sehen wo der Fehler liegt.
Also was macht:
select count(*) as eins from tabelle where 'Kanten SOLL' = 'Kanten IST'
und könnte das Ergebnis stimmen?
Und was das Datumsformat angeht, aus dem Technet:
Wir empfehlen, Datums- und Zeitformate zu verwenden, die nicht von DATEFORMAT abhängen und mehrere Sprachen unterstützen. Die ISO 8601-Formate "1998-02-23T14:23:05" und "1998-02-23T14:23:05 -08:00" sind die einzigen Formate, die als internationaler Standard gelten. Sie sind nicht von DATEFORMAT oder der bei der Anmeldung angegebenen Standardsprache abhängig und unterstützen mehrere Sprachen.
Wenn ein verknüpftes Statement nicht tut, verifiziert man zuerst einmal, ob die zugrundeliegenden Statements funktionieren.
D.h. funktionieren die Selects einzeln? Und tun Sie das, was sie sollen?
select count(*) as eins from tabelle where 'Kanten SOLL' = 'Kanten IST' and 'Kanten SOLL' between '29.07.2013' and '02.08.2013'
und
select count(*) as zwei from tabelle where 'Kanten SOLL' between '29.07.2013' and '02.08.2013'
Und wenn Sie nicht tun, vereinfacht man das Statement, um zu sehen wo der Fehler liegt.
Also was macht:
select count(*) as eins from tabelle where 'Kanten SOLL' = 'Kanten IST'
und könnte das Ergebnis stimmen?
Und was das Datumsformat angeht, aus dem Technet:
Wir empfehlen, Datums- und Zeitformate zu verwenden, die nicht von DATEFORMAT abhängen und mehrere Sprachen unterstützen. Die ISO 8601-Formate "1998-02-23T14:23:05" und "1998-02-23T14:23:05 -08:00" sind die einzigen Formate, die als internationaler Standard gelten. Sie sind nicht von DATEFORMAT oder der bei der Anmeldung angegebenen Standardsprache abhängig und unterstützen mehrere Sprachen.
Moinmoin,
also erstmal das select von EricAG3: da fehlt hinter den beiden Unterabfragen einfach nur ein Alias:
Die implizite Umwandlung des Datums funktioniert zwar normalerweise, aber besser wäre es natürlich, es explizit per cast oder convert ins Datumsformat zu bringen.
Der Ansatz von LianenSchwinger würde mit einer kleinen Änderung auch funktionieren:
Im Übrigen sollte man bei Divisionen auch immer prüfen, ob der Nenner 0 ist.
Gruß, Mad Max
also erstmal das select von EricAG3: da fehlt hinter den beiden Unterabfragen einfach nur ein Alias:
select eins / zwei
from
(select count(*) as eins from tabelle where [Kanten SOLL] = [Kanten IST] and [Kanten SOLL] between '29.07.2013' and '02.08.2013') AS A,
(select count(*) as zwei from tabelle where [Kanten SOLL] between '29.07.2013' and '02.08.2013') AS B;
Die implizite Umwandlung des Datums funktioniert zwar normalerweise, aber besser wäre es natürlich, es explizit per cast oder convert ins Datumsformat zu bringen.
Der Ansatz von LianenSchwinger würde mit einer kleinen Änderung auch funktionieren:
SELECT SUM (CASE [Kanten SOLL] WHEN [Kanten IST] THEN 1 ELSE 0 END) / COUNT(*)
FROM tabelle
WHERE [Kanten SOLL] BETWEEN '29.07.2013' AND '02.08.2013'
Im Übrigen sollte man bei Divisionen auch immer prüfen, ob der Nenner 0 ist.
Gruß, Mad Max
Du hast nur die Lösungen von Biber und LianenSchwinger ausprobiert, die geben natürlich 0 aus. Wenn [Kanten SOLL] und [Kanten IST] statt mit eckigen Klammern oder doppelten Anführungszeichen mit einfachen Anführungszeichen umschlossen werden, sind es keine Spaltennamen, sondern Zeichenfolgen. Folglich ergibt
immer 0 bzw. ohne ELSE NULL, weil die Zeichenfolgen eben nicht gleich sind.
Gruß, Mad Max
CASE 'Kanten SOLL' WHEN 'Kanten IST' THEN 1 ELSE 0 END
Gruß, Mad Max
Unsere Vorschläge haben sich genau auf das bezogen, was du gepostet hast, in Deinem Posting stehen die Spaltennamen mit einem einfachen Anführungszeichen, Deine jetzt oben geposteten mit doppelten Anführungszeichen.
Das macht einen Unterschied, wie Mad Max schon festgestellt hat. Und wir gehen hier davon aus, das man die Statements per Copy & Paste ins Posting packt und damit in Deinem Original auch einfache Anführungszeichen drin sind.
Aber der Vorschlag von Mad Max sollte doch eigentlich tun, was kommt bei dem denn?
Das macht einen Unterschied, wie Mad Max schon festgestellt hat. Und wir gehen hier davon aus, das man die Statements per Copy & Paste ins Posting packt und damit in Deinem Original auch einfache Anführungszeichen drin sind.
Aber der Vorschlag von Mad Max sollte doch eigentlich tun, was kommt bei dem denn?
Tja, peinlich, das lerne ich in diesem Leben wahrscheinlich nicht mehr: zwei int-Werte dividiert ergibt wieder int. Also muß Zähler oder Nenner in float oder dec o.ä. konvertiert werden:
Wenns jetzt nicht paßt geb ich auf.
Gruß, Mad Max
SELECT SUM (CASE [Kanten SOLL] WHEN [Kanten IST] THEN 1 ELSE 0 END) / convert (float, COUNT(*))
FROM tabelle
WHERE [Kanten SOLL] BETWEEN '29.07.2013' AND '02.08.2013'
Wenns jetzt nicht paßt geb ich auf.
Gruß, Mad Max
Moin EricAG3,
Das Statement IST einfacher als dein Ansatz - schau nochmal hin.
Also nicht einen Wert "0,28763", sondern nur den ganzzahligen Teil--> 0.
Hast du in irgendwelche QuadCore-Aktien investiert oder meinst du, wir sollten rumprassen, solange wir jung sind?
Abgesehen davon - die Länge oder Kürze eines Select-Statements sagt wenig aus über Effizienz, Performanz und Wartbarkeit.
Dennoch ist das erste Statement/dein Lösungsansatz doch wohl tippfehlerträchtiger (alle Feld-/Tabellennamen+Parameter müssen an zwei Stellen angepasst werden) und wirklich bei einer Tabelle mit mehr als 50 Sätzen bestimmt auch nicht performanter.
Auch nicht bei 5 Sätzen.
Ach ja, und wenn du das CASTen auf float nicht magst: du brauchst ja nur in der Rechnung eine Nicht-Ganzzahl mit einbauen.
Grüße
Biber
Das Statement IST einfacher als dein Ansatz - schau nochmal hin.
gerade dieses konvertieren in float verstehe ich nicht, wieso war das nötig?
Das wurde gerade erklärt - eine Ganzzahl ( Beispiel: 15) geteilt durch eine andere Ganzzahl (Beispiel 52) ergibt wieder eine Ganzzahl.Also nicht einen Wert "0,28763", sondern nur den ganzzahligen Teil--> 0.
und geht es nicht indem man die zwei von mir erstellen selects irgendwie hintereinander abfragt?
dann wären wir näher an meiner lösung...
Und weiter? Was ist erstrebenswert daran, für das Anzeigen EINES Wertes ZWEIMAL einen Count(*) mit derselben WHERE-Clause auf dieselbe Tabelle zu machen?dann wären wir näher an meiner lösung...
Hast du in irgendwelche QuadCore-Aktien investiert oder meinst du, wir sollten rumprassen, solange wir jung sind?
Abgesehen davon - die Länge oder Kürze eines Select-Statements sagt wenig aus über Effizienz, Performanz und Wartbarkeit.
Dennoch ist das erste Statement/dein Lösungsansatz doch wohl tippfehlerträchtiger (alle Feld-/Tabellennamen+Parameter müssen an zwei Stellen angepasst werden) und wirklich bei einer Tabelle mit mehr als 50 Sätzen bestimmt auch nicht performanter.
Auch nicht bei 5 Sätzen.
Ach ja, und wenn du das CASTen auf float nicht magst: du brauchst ja nur in der Rechnung eine Nicht-Ganzzahl mit einbauen.
... Select ..(sum(eins) * 100.00 /count(*) ) as LieferTroieInProzent
Grüße
Biber