Twoje zapytanie będzie już działać — z wyjątkiem tego, że napotykasz konflikty nazw lub po prostu mylisz kolumnę danych wyjściowych (CASE
wyrażenie) z kolumną źródłową result
, który ma inną treść.
...
GROUP BY model.name, attempt.type, attempt.result
...
Musisz GROUP BY
Twój CASE
wyrażenie zamiast kolumny źródłowej:
...
GROUP BY model.name, attempt.type
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END
...
Lub podaj alias kolumny to jest inne niż jakakolwiek nazwa kolumny w FROM
lista - w przeciwnym razie ta kolumna ma pierwszeństwo:
SELECT ...
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END AS result1
...
GROUP BY model.name, attempt.type, result1
...
Pod tym względem standard SQL jest dość specyficzny. Cytując instrukcję tutaj:
Nazwa kolumny wyjściowej może być używana do odwoływania się do wartości kolumny w ORDER BY
i GROUP BY
klauzul, ale nie w WHERE
lub HAVING
klauzul;w zamian musisz napisać wyrażenie.
Oraz:
Jeśli ORDER BY
wyrażenie to prosta nazwa, która pasuje zarówno do nazwy kolumny wyjściowej, jak i nazwy kolumny wejściowej, ORDER BY
zinterpretuje to jako nazwę kolumny wyjściowej. Jest to przeciwieństwo wyboru GROUP BY
sprawi, że w tej samej sytuacji. Ta niespójność ma być kompatybilna ze standardem SQL.
Pogrubienie podkreślenie moje.
Tych konfliktów można uniknąć, używając odniesień pozycyjnych (liczby porządkowe) w GROUP BY
i ORDER BY
, odwołując się do elementów w SELECT
lista od lewej do prawej. Zobacz rozwiązanie poniżej.
Wadą jest to, że może to być trudniejsze do odczytania i podatne na edycje w SELECT
listę (można zapomnieć o odpowiednim dostosowaniu referencji pozycyjnych).
Ale nie trzeba dodać kolumnę day
do GROUP BY
klauzula, o ile zawiera stałą wartość (CURRENT_DATE-1
).
Przepisany i uproszczony z odpowiednią składnią JOIN i referencjami pozycyjnymi może wyglądać tak:
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;
Zauważ też, że unikam nazwy kolumny time
. To zastrzeżone słowo i nigdy nie powinno być używane jako identyfikator. Poza tym twój „czas” to oczywiście timestamp
lub date
, więc jest to raczej mylące.