Sua consulta já funcionaria - exceto que você está enfrentando conflitos de nomenclatura ou apenas confundindo a coluna de saída (o
CASE expressão) com coluna de origem result , que tem conteúdo diferente. ...
GROUP BY model.name, attempt.type, attempt.result
... Você precisa
GROUP BY seu CASE expressão em vez de sua coluna de origem:...
GROUP BY model.name, attempt.type
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END
... Ou forneça um alias de coluna que é diferente de qualquer nome de coluna no
FROM list - ou então essa coluna tem precedência:SELECT ...
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END AS result1
...
GROUP BY model.name, attempt.type, result1
... O padrão SQL é bastante peculiar a esse respeito. Citando o manual aqui:
O nome de uma coluna de saída pode ser usado para se referir ao valor da coluna emORDER BYeGROUP BYcláusulas, mas não noWHEREouHAVINGcláusulas; lá você deve escrever a expressão.
E:
Se umORDER BYexpressão é um nome simples que corresponde a um nome de coluna de saída e a um nome de coluna de entrada,ORDER BYirá interpretá-lo como o nome da coluna de saída. Isso é o oposto da escolha queGROUP BYfará na mesma situação. Essa inconsistência é feita para ser compatível com o padrão SQL.
Negrito ênfase minha.
Esses conflitos podem ser evitados usando referências posicionais (números ordinais) em
GROUP BY e ORDER BY , referenciando itens no SELECT lista da esquerda para a direita. Veja a solução abaixo.A desvantagem é que isso pode ser mais difícil de ler e vulnerável a edições no
SELECT list (pode-se esquecer de adaptar as referências posicionais de acordo). Mas você não tem que adicionar a coluna
day para o GROUP BY cláusula, desde que mantenha um valor constante (CURRENT_DATE-1 ). Reescrito e simplificado com a sintaxe JOIN adequada e referências posicionais, poderia ficar assim:
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; Observe também que estou evitando o nome da coluna
time . Essa é uma palavra reservada e nunca deve ser usada como identificador. Além disso, seu "tempo" obviamente é um timestamp ou date , de modo que é bastante enganador.