Alguns pontos importantes sobre como usar SQL:
- Você não pode usar apelidos de coluna na cláusula WHERE, mas você pode na cláusula HAVING. Essa é a causa do erro que você tem.
- Você pode fazer a sua contagem de melhor utilizar um JOIN e GROUP BY que usando subconsultas correlacionadas. Vai ser muito mais rápido.
- Utilizar a cláusula HAVING para filtrar grupos.
Aqui é a maneira que eu ia escrever esta consulta:
SELECT t1.id, COUNT(t2.id) AS num_things
FROM t1 JOIN t2 USING (id)
GROUP BY t1.id
HAVING num_things = 5;
Sei que esta consulta pode pular o JOINcom t1, como na solução de Charles Bretana. Mas eu suponho que você pode querer a consulta para incluir algumas outras colunas de t1.
Re: a pergunta no comentário:
A diferença é que a WHEREcláusula é avaliada em linhas, antes GROUP BYreduz grupos para uma única linha por grupo. A HAVINGcláusula é avaliada depois os grupos são formados. Então você não pode, por exemplo, mudar o COUNT()de um grupo usando HAVING; você só pode excluir o próprio grupo.
SELECT t1.id, COUNT(t2.id) as num
FROM t1 JOIN t2 USING (id)
WHERE t2.attribute = <value>
GROUP BY t1.id
HAVING num > 5;
Na consulta acima, WHEREFiltros para linhas correspondentes uma condição, e HAVINGfiltros para os grupos que têm pelo menos cinco contagem.
O ponto que causa confusão a maioria das pessoas é quando eles não têm uma GROUP BYcláusula, por isso parece como HAVINGe WHEREsão intercambiáveis.
WHEREé avaliada antes expressões na lista de seleção. Isto pode não ser óbvio porque a sintaxe SQL coloca o select-lista em primeiro lugar. Então você pode salvar um monte de computação caro usando WHEREpara restringir linhas.
SELECT <expensive expressions>
FROM t1
HAVING primaryKey = 1234;
Se você usar uma consulta como o acima, as expressões na lista de seleção são computados para cada linha , apenas para descartar a maioria dos resultados por causa da HAVINGcondição. No entanto, a consulta abaixo calcula a expressão apenas para a única linha correspondentes a WHEREcondição.
SELECT <expensive expressions>
FROM t1
WHERE primaryKey = 1234;
Então, para recapitular, as consultas são executadas pelo mecanismo de banco de dados de acordo com a série de passos:
- Gerar um conjunto de linhas da tabela (s), incluindo quaisquer linhas produzidas pela
JOIN.
- Avaliar
WHEREcondições contra o conjunto de linhas, filtrando as linhas que não correspondem.
- Calcule expressões na lista de seleção para cada no conjunto de linhas.
- Aplicar aliases de coluna (note que este é um passo separado, o que significa que você não pode usar aliases em expressões na lista de seleção).
- Condensar grupos de uma única linha por grupo, de acordo com a
GROUP BYcláusula.
- Avaliar
HAVINGcondições contra grupos, filtrando grupos que não combinam.
- Ordenar resultar, de acordo com a
ORDER BYcláusula.