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.