Votre requête fonctionnerait déjà - sauf que vous rencontrez des conflits de nom ou que vous confondez simplement la colonne de sortie (le CASE expression) avec colonne source result , qui a un contenu différent.
...
GROUP BY model.name, attempt.type, attempt.result
...
Vous devez GROUP BY votre CASE expression au lieu de votre colonne source :
...
GROUP BY model.name, attempt.type
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END
...
Ou fournissez un alias de colonne qui est différent de tout nom de colonne dans le FROM list - sinon cette colonne est prioritaire :
SELECT ...
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END AS result1
...
GROUP BY model.name, attempt.type, result1
... Le standard SQL est assez particulier à cet égard. Citant le manuel ici :
Le nom d'une colonne de sortie peut être utilisé pour faire référence à la valeur de la colonne dans
ORDER BYetGROUP BYclauses, mais pas dansWHEREouHAVINGclauses ; là, vous devez écrire l'expression à la place.
Et :
Si un
ORDER BYexpression est un nom simple qui correspond à la fois à un nom de colonne de sortie et à un nom de colonne d'entrée,ORDER BYl'interprétera comme le nom de la colonne de sortie. C'est le contraire du choix queGROUP BYfera dans la même situation. Cette incohérence est faite pour être compatible avec le standard SQL.
Gras c'est moi qui souligne.
Ces conflits peuvent être évités en utilisant des références positionnelles (nombres ordinaux) dans GROUP BY et ORDER BY , faisant référence aux éléments dans le SELECT liste de gauche à droite. Voir la solution ci-dessous.
L'inconvénient est que cela peut être plus difficile à lire et vulnérable aux modifications dans le SELECT liste (on pourrait oublier d'adapter les références de position en conséquence).
Mais vous ne le faites pas il faut ajouter la colonne day au GROUP BY clause, tant qu'elle contient une valeur constante (CURRENT_DATE-1 ).
Réécrit et simplifié avec une syntaxe JOIN appropriée et des références de position, il pourrait ressembler à ceci :
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;
Notez également que j'évite le nom de colonne time . C'est un mot réservé et ne doit jamais être utilisé comme identifiant. De plus, votre "heure" est évidemment un timestamp ou date , donc c'est plutôt trompeur.