Estou desenvolvendo uma aplicação estatística para analisar respostas de um questionário socieconômico de alunos ingressantes de uma universidade. Preciso fazer consultas do tipo “Quantidade de mulheres entre 17 e 20 anos” (só um exemplo). Estou utilizando o comando COUNT nos SQLs e está tudo funcionando, porém encontrei um pequeno problema: quando não há nenhuma mulher entre 17 e 20 anos, o resultado da consulta não retorna linha nenhuma e eu precisava que retornasse o valor 0. Tentei usar COALESCE(nome_do_campo, 0), porém não funciona. Já pesquisei bastante na net. Alguém poderia me ajudar a resolver isso ou realmente não tem solução via SQL?
Estou usando MySQL e um CASE também não funcionou… já utilzei Firebird e SQL Server e me lembro que isso funcionava nesses BDs. O estranho dessa situação é que nem um NULL é exibido, ou seja, não mostra linha nenhuma no resultado quando não há dados.
SELECT A.DESCRICAO,
CASE WHEN COUNT(AL.ID) > 0 THEN COUNT(AL.ID) ELSE 0 END AS TOTAL
FROM ALUNOS AL
INNER JOIN RESPOSTAS R ON R.ALUNO = AL.ID AND R.PERGUNTA = 5
INNER JOIN ALTERNATIVAS A ON R.ALTERNATIVA = A.ID
WHERE AL.ANO = 2012
GROUP BY A.LETRA
ORDER BY A.LETRA
No Oracle, ao executar a seguinte query, que retornará 0 linhas…
… a saída é o número 0. Não sei bem como deve funcionar isso no MySQL, mas deveria ter o mesmo comportamento, visto que essa é uma cláusula comum a todos os bancos que adotam o padrão ANSI SQL. Não ocorre nenhum erro durante a execução de seu código?
[quote=FabricioPJ]No Oracle, ao executar a seguinte query, que retornará 0 linhas…
… a saída é o número 0. Não sei bem como deve funcionar isso no MySQL, mas deveria ter o mesmo comportamento, visto que essa é uma cláusula comum a todos os bancos que adotam o padrão ANSI SQL. Não ocorre nenhum erro durante a execução de seu código?[/quote]
Então, no Firebird e SQL Server só assim também sairia 0 D:
Não dá nenhum erro, não. Os valores aparecem corretamente para a query que eu postei nos comentários de cima ai, porém a linha que não tem dados não é exibida ao invés de mostrar 0
A sintaxe de utilização dela é igual a do COALESCE, só que é específica do MySQL, se não me engano// Com IFNULL
SELECT ProductName,UnitPrice*(UnitsInStock+IFNULL(UnitsOnOrder,0)) FROM Products
// Com COALESCE
SELECT ProductName,UnitPrice*(UnitsInStock+COALESCE(UnitsOnOrder,0)) FROM Productshttp://www.w3schools.com/sql/sql_isnull.asp
SELECT A.DESCRICAO,
CASE WHEN COUNT(AL.ID) IS NOT NULL THEN COUNT(AL.ID) ELSE 0 END AS TOTAL
FROM ALUNOS AL
INNER JOIN RESPOSTAS R ON R.ALUNO = AL.ID AND R.PERGUNTA = 5
INNER JOIN ALTERNATIVAS A ON R.ALTERNATIVA = A.ID
WHERE AL.ANO = 2012
GROUP BY A.LETRA
ORDER BY A.LETRA
Ou
SELECT A.DESCRICAO,
IF COUNT(AL.ID) IS NOT NULL THEN COUNT(AL.ID) ELSE 0 END AS TOTAL
FROM ALUNOS AL
INNER JOIN RESPOSTAS R ON R.ALUNO = AL.ID AND R.PERGUNTA = 5
INNER JOIN ALTERNATIVAS A ON R.ALTERNATIVA = A.ID
WHERE AL.ANO = 2012
GROUP BY A.LETRA
ORDER BY A.LETRA
[quote=digaoneves]A sintaxe de utilização dela é igual a do COALESCE, só que é específica do MySQL, se não me engano// Com IFNULL
SELECT ProductName,UnitPrice*(UnitsInStock+IFNULL(UnitsOnOrder,0)) FROM Products
// Com COALESCE
SELECT ProductName,UnitPrice*(UnitsInStock+COALESCE(UnitsOnOrder,0)) FROM Productshttp://www.w3schools.com/sql/sql_isnull.asp[/quote]
SELECT A.DESCRICAO,
CASE WHEN COUNT(AL.ID) IS NOT NULL THEN COUNT(AL.ID) ELSE 0 END AS TOTAL
FROM ALUNOS AL
INNER JOIN RESPOSTAS R ON R.ALUNO = AL.ID AND R.PERGUNTA = 5
INNER JOIN ALTERNATIVAS A ON R.ALTERNATIVA = A.ID
WHERE AL.ANO = 2012
GROUP BY A.LETRA
ORDER BY A.LETRA
Ou
SELECT A.DESCRICAO,
IF COUNT(AL.ID) IS NOT NULL THEN COUNT(AL.ID) ELSE 0 END AS TOTAL
FROM ALUNOS AL
INNER JOIN RESPOSTAS R ON R.ALUNO = AL.ID AND R.PERGUNTA = 5
INNER JOIN ALTERNATIVAS A ON R.ALTERNATIVA = A.ID
WHERE AL.ANO = 2012
GROUP BY A.LETRA
ORDER BY A.LETRA
[/quote]
O primeiro rodou, porém ainda não funcionou D:
O segundo está dando erro de sintaxe
Veja a dica do abelbueno. Inner joins só consideram os valores que existem nas duas tabelas. Caso queira valores, independente de existirem em A ou B, precisa do left join.
AbelBueno, entendi o que você quis dizer, porém eu tenho uma tabela ALTERNATIVAS que contém as opções “16 anos”, “17 anos”, “18 anos”, etc. Só que nenhum registro da tabela ALUNOS está vinculado à alternativa “16 anos”. Nesse caso ele saberia da existência do “16 anos”, certo? Seria o caso de mudar pra LEFT JOIN então?
É, isso ta bem estranho, a gente até poderia sugerir outras opções de como verificar se o resultado está vindo Null, como:SELECT A.DESCRICAO,
CASE WHEN ISNULL(COUNT(AL.ID)) THEN 0 ELSE COUNT(AL.ID) END AS TOTAL
FROM ALUNOS AL
INNER JOIN RESPOSTAS R ON R.ALUNO = AL.ID AND R.PERGUNTA = 5
INNER JOIN ALTERNATIVAS A ON R.ALTERNATIVA = A.ID
WHERE AL.ANO = 2012
GROUP BY A.LETRA
ORDER BY A.LETRA Porém aparentemente o problema é que não está retornando nada (o que eu nunca vi acontecer), porque se estivesse vindo nulo, o COALESCE ja resolveria.