Retornar 0 em Select

23 respostas Resolvido
R

Tenho a seguinte SELECT:

SELECT IFNULL(SUM(valor), 0) AS valor FROM pedidos WHERE data BETWEEN '2015-10-01' AND '2015-10-31' GROUP BY id_supervisor

quando o supervisor nao tem registto no campo SUM(valor) como faço para me retornar 0?

Quando não tem valor ele nao me retorna o registro

23 Respostas

R

Se o supervisor não tem linhas correspondentes na tabela pedidos, mas você precisa incluí-lo na consulta, então você precisa fazer uma LEFT JOIN pela tabela de supervisores:

SELECT s.id_supervisor as nome_supervisor , SUM(IFNULL(p.valor,0))  as total_pedidos
FROM supervisor s
LEFT JOIN pedidos p on (s.id = p.id_supervisor)
GROUP BY s.id_supervisor
R

Fiz assim:

SELECT s._id, s.nome, IFNULL(SUM(p.valor),0) as valor_total FROM supervisor s LEFT JOIN pedidos p on s._id = p.id_supervisor WHERE data BETWEEN '2015-11-01' AND '2015-11-30' GROUP BY s._id

Mas continua não me retornando os supervisores com valores 0.

R

Tentou colocar o IFNULL dentro da função SUM() ?

R

Sim, tentei fazer como você postou, mas da este erro:

wrong number of arguments to function IFNULL()

Estou usando SQLite

R

eu tinha errado os parênteses:

SUM(IFNULL(valor,0))

R

Fiz assim:

SELECT s._id, s.nome, SUM(IFNULL(p.valor,0)) as total_pedidos FROM supervisor s LEFT JOIN pedidos p on s._id = p.id_supervisor WHERE data BETWEEN '2016-11-01' AND '2016-11-30' GROUP BY s._id

Continua me retornando apenas supervisores que contem valores na tabela pedidos

Minhas tabelas são assim:
Tabela Supervisor
_id
nome

Tabela Pedidos:
_id
id_supervisor
data
valor

R

Execute esta query:

select count(s._id) from supervisor s where s._id not in ( select distinct p.id_supervisor from pedidos p where p.data BETWEEN '2016-11-01' AND '2016-11-30' )

se o resultado for 0 é porque todos os supervisores tem pedidos.

R

resultado 2, então 2 supervisores não tem pedidos.

É isso mesmo que tem no BD
Tenho 3 supervisores, neste intervalo de data apenas 1 tem pedidos. Mas preciso retornar os outros 2 com valores zerados

R

Tente trocar o LEFT JOIN por LEFT OUTER JOIN

R

já tinha tentado, continuou não retornando

R

Pensei que o LEFT JOIN nao era suportado pelo SQLITE.
Mas conferi a documentação e não dá suporte apenas para RIGHT OUTER JOIN e
FULL OUTER JOIN.

LEFT OUTER JOIN is implemented, but not RIGHT OUTER JOIN or
FULL OUTER JOIN.

Então era para estar funcionando este SELECT…

R

Tá estranho mesmo isso, execute esse comando e poste o resultado:

EXPLAIN QUERY PLAN SELECT s._id, s.nome, p.valor
FROM supervisor s
LEFT JOIN pedidos p on s._id = p.id_supervisor
WHERE data BETWEEN '2016-11-01' AND '2016-11-30'
GROUP BY s._id
R

aliás, é interessante testar a query sem o SUM()

R

Fiz assim sem o SUM:

SELECT s._id, s.nome, IFNULL(p.valor,0) as total_pedidos FROM supervisor s LEFT JOIN pedidos p on s._id = p.id_supervisor WHERE data BETWEEN '2016-11-01' AND '2016-11-30' GROUP BY s._id

Continuou não retornando

E o resultado da sua query foi esse:

Executando a query pelo cmd teve mais alguns detalhes:

R

Cara, o plano de execução tá normal, ele faz o table scan na pedidos e depois recupera as linhas do pedido. Tenta trocar a ordem das tabela no join:

SELECT s._id, s.nome, p.valor
FROM pedidos p
LEFT JOIN  supervisor s on s._id = p.id_supervisor
WHERE data BETWEEN '2016-11-01' AND '2016-11-30'
R

Também não retornou os supervisores sem pedidos

P

Os supervisores não têm pedidos ou não tem pedidos nas datas indicadas?

P
Solucao aceita

O que tu precisas, provavelmente, é:

select s.id, s.nome, (select sum(p.valor) from pedidos p where p.id_supervisor = s.id and p.data between '2016-11-01' AND '2016-11-30') as valor from supervisor s

R

De 3 supervisores apenas 1 tem pedidos na data indica.

Com seu exemplo deu certo…
Fiz assim:

SELECT s._id, s.nome, (SELECT IFNULL(SUM(p.valor),0) FROM pedidos p WHERE p.id_supervisor = s._id AND p.data BETWEEN '2016-11-01' AND '2016-11-30') AS valor FROM supervisor s

Vlw…
Porque do outro modo não dava certo?

Z

Eu uso a função COALESCE exemplo COALESCE(sum(meu campo), 0) se o valor for nulo ele retorna ZERO

S

SELECT * FROM supervisor; SELECT * FROM pedidos
SELECT
	SUB.id, SUB.nome, CASE WHEN SUB.ValorPedidos IS NULL THEN 0 ELSE SUB.ValorPedidos END AS ValorPedidos
FROM(
	SELECT
	    supervisor.id, supervisor.nome,
	    (SELECT SUM(VALOR) FROM PEDIDOS WHERE pedidos.id_supervisor = supervisor.id)ValorPedidos
    FROM supervisor
)AS SUB
R

Cara, fiz igual o plml disse:

SELECT s._id, s.nome, (SELECT IFNULL(SUM(p.valor),0) FROM pedidos p WHERE p.id_supervisor = s._id AND p.data BETWEEN '2016-11-01' AND '2016-11-30') AS valor FROM supervisor s

Mas vlw, outra forma de se fazer.

P

existe a função NVL para isso, e deve ser utilizado assim:

SELECT NVL(SUM(valor), 0) AS valor FROM pedidos
WHERE data BETWEEN ‘2015-10-01’ AND '2015-10-31’
GROUP BY id_supervisor

Criado 22 de janeiro de 2016
Ultima resposta 22 de jan. de 2016
Respostas 23
Participantes 6