Ihre Abfrage würde bereits funktionieren - außer dass Sie auf Namenskonflikte stoßen oder nur die Ausgabespalte verwirren (der CASE
Ausdruck) mit Quellspalte result
, die einen anderen Inhalt hat.
...
GROUP BY model.name, attempt.type, attempt.result
...
Sie müssen GROUP BY
verwenden Ihr CASE
Ausdruck anstelle Ihrer Quellspalte:
...
GROUP BY model.name, attempt.type
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END
...
Oder geben Sie einen Spaltenalias an das unterscheidet sich von allen Spaltennamen in FROM
list - oder diese Spalte hat Vorrang:
SELECT ...
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END AS result1
...
GROUP BY model.name, attempt.type, result1
...
Der SQL-Standard ist in dieser Hinsicht ziemlich eigenartig. Zitieren Sie das Handbuch hier:
Der Name einer Ausgabespalte kann verwendet werden, um auf den Wert der Spalte in ORDER BY
zu verweisen und GROUP BY
-Klauseln, aber nicht im WHERE
oder HAVING
Klauseln; dort müssen Sie stattdessen den Ausdruck ausschreiben.
Und:
Wenn ein ORDER BY
Ausdruck ist ein einfacher Name, der sowohl mit einem Ausgabespaltennamen als auch mit einem Eingabespaltennamen übereinstimmt, ORDER BY
interpretiert ihn als den Namen der Ausgabespalte. Dies ist das Gegenteil von GROUP BY
machen in der gleichen Situation. Diese Inkonsistenz soll mit dem SQL-Standard kompatibel sein.
Fett Hervorhebung von mir.
Diese Konflikte können durch Verwendung von Positionsreferenzen vermieden werden (Ordnungszahlen) in GROUP BY
und ORDER BY
, die Elemente in SELECT
referenzieren Liste von links nach rechts. Siehe Lösung unten.
Der Nachteil ist, dass dies möglicherweise schwieriger zu lesen und anfällig für Änderungen im SELECT
ist Liste (man könnte vergessen, Positionsreferenzen entsprechend anzupassen).
Aber Sie nicht muss die Spalte day
hinzugefügt werden zu GROUP BY
-Klausel, solange sie einen konstanten Wert enthält (CURRENT_DATE-1
).
Umgeschrieben und vereinfacht mit der richtigen JOIN-Syntax und Positionsreferenzen könnte es so aussehen:
SELECT m.name
, a.type
, CASE WHEN a.result = 0 THEN 0 ELSE 1 END AS result
, CURRENT_DATE - 1 AS day
, count(*) AS ct
FROM attempt a
JOIN prod_hw_id p USING (hard_id)
JOIN model m USING (model_id)
WHERE ts >= '2013-11-06 00:00:00'
AND ts < '2013-11-07 00:00:00'
GROUP BY 1,2,3
ORDER BY 1,2,3;
Beachten Sie auch, dass ich den Spaltennamen time
vermeide . Das ist ein reserviertes Wort und sollte niemals als Bezeichner verwendet werden. Außerdem ist Ihre "Zeit" offensichtlich ein timestamp
oder date
, das ist also ziemlich irreführend.