Váš dotaz by již fungoval – až na to, že se dostáváte do konfliktů názvů nebo si jen pletete výstupní sloupec (CASE
výraz) se zdrojovým sloupcem result
, která má jiný obsah.
...
GROUP BY model.name, attempt.type, attempt.result
...
Musíte GROUP BY
váš CASE
výraz místo vašeho zdrojového sloupce:
...
GROUP BY model.name, attempt.type
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END
...
Nebo zadejte alias sloupce který se liší od názvu kteréhokoli sloupce v FROM
seznam – jinak má tento sloupec přednost:
SELECT ...
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END AS result1
...
GROUP BY model.name, attempt.type, result1
...
Standard SQL je v tomto ohledu poněkud zvláštní. Zde cituji manuál:
Název výstupního sloupce lze použít jako odkaz na hodnotu sloupce v
ORDER BY
aGROUP BY
klauzule, ale ne vWHERE
neboHAVING
klauzule; tam musíte místo toho napsat výraz.
A:
Pokud
ORDER BY
výraz je jednoduchý název, který odpovídá názvu výstupního sloupce i názvu vstupního sloupce,ORDER BY
bude to interpretovat jako název výstupního sloupce. Toto je opak volbyGROUP BY
udělá ve stejné situaci. Tato nekonzistence je navržena tak, aby byla kompatibilní se standardem SQL.
Tučné zdůrazněte můj.
Těmto konfliktům se lze vyhnout pomocí pozičních referencí (řadová čísla) v GROUP BY
a ORDER BY
, odkazující na položky v SELECT
seznam zleva doprava. Viz řešení níže.
Nevýhodou je, že to může být hůře čitelné a náchylné na úpravy v SELECT
seznam (možná zapomenete odpovídajícím způsobem upravit poziční reference).
Ale vy ne musíte přidat sloupec day
do GROUP BY
klauzule, pokud má konstantní hodnotu (CURRENT_DATE-1
).
Přepsané a zjednodušené se správnou syntaxí JOIN a pozičními odkazy by to mohlo vypadat takto:
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;
Všimněte si také, že se vyhýbám názvu sloupce time
. Toto je vyhrazené slovo a nikdy by se nemělo používat jako identifikátor. Kromě toho, váš "čas" je samozřejmě timestamp
nebo date
, takže je to spíše zavádějící.