[RESOLVIDO] Retornar dados que foram suprimidos pelo WHERE do SELECT

Boa tarde a todos. Estou usando o SGBD MySQL 5.7 e estou tendo dificuldade para montar uma consulta para a geração de um gráfico.

Eu estou retornando da minha tabela de pagamentos a soma dos valores, agrupados pela data, cuja forma de pagamento seja cartão de crédito por exemplo. Até aí tudo normal segue exemplos das consutas e os dados retornados:

SELECT data, SUM(valor) 
FROM pagamentos 
WHERE forma_pagamento = 'CREDITO' 
GROUP BY data;

+---------------------+------------+
| data                | SUM(valor) | #Retorno dos pagamentos no cartão de crédito.
+---------------------+------------+
| 2018-06-07 00:00:00 |     500.00 |
+---------------------+------------+

SELECT data, SUM(valor) 
FROM pagamentos 
WHERE forma_pagamento = 'DINHEIRO' 
GROUP BY data;

+---------------------+------------+
| data                | SUM(valor) | #Retorno dos pagamentos em dinheiro.
+---------------------+------------+
| 2018-05-02 00:00:00 |     480.00 |
| 2018-05-03 00:00:00 |      65.00 |
| 2018-06-07 00:00:00 |     100.00 |
+---------------------+------------+

O que eu preciso é que o resultado da primeira consulta seja este:

+---------------------+------------+
| data                | SUM(valor) |
+---------------------+------------+
| 2018-05-02 00:00:00 |       0.00 |
| 2018-05-03 00:00:00 |       0.00 |
| 2018-06-07 00:00:00 |     500.00 |
+---------------------+------------+

Ou seja caso existam pagamentos com outra forma_pagamento (‘DINHEIRO’ por exemplo) em uma data que não tenha tido pagamento em cartao, que esta data seja retornada com o valor 0. (Nesta data houveram pagamentos mas como não foi em cartão retorna-se a data com o valor 0).

Segue a descrição da minha tabela caso necessário:

+----------------------+---------------+------+-----+---------+----------------+
| Field                | Type          | Null | Key | Default | Extra          |
+----------------------+---------------+------+-----+---------+----------------+
| id                   | int(11)       | NO   | PRI | NULL    | auto_increment |
| bandeira_cartao      | varchar(255)  | YES  |     | NULL    |                |
| data                 | datetime      | YES  |     | NULL    |                |
| forma_pagamento      | varchar(255)  | YES  |     | NULL    |                |
| qtd_parcelas         | int(11)       | YES  |     | NULL    |                |
| valor                | decimal(19,2) | YES  |     | NULL    |                |
| cliente_numero_ficha | int(11)       | NO   | MUL | NULL    |                |
| cliente_ortodontia   | bit(1)        | NO   |     | NULL    |                |
+----------------------+---------------+------+-----+---------+----------------+

Eu procurei bastante sobre como fazer isso mas não encontrei nada parecido. Agradeço a quem puder ajudar. :wink:

Pelo jeito, a pesquisa não foi tão boa, né?
Não encontrou nem o IN.
Além disso, você deve colocar uma condição (CASE) para as situações em que seja necessário setar como 0 o valor.

Eu só consigo selecionar os pagamentos no cartao usando o where e ele remove do resultado as outras datas. A query tem que continuar funcionando quando os dados do banco mudarem, já tinha tentado com IN e com IF mas não progredi. Tem certeza do que está falando? Você consegue resolver só colocanado in e case ?

Uma forma de fazer isso é primeiro dar um select distinct nas datas da tabela pagamento, fazendo um left join com a sua query original (pela data).

2 curtidas
SELECT
  data,
  CASE
    WHEN forma_pagamento = 'CREDITO' THEN SUM(VALOR)
    ELSE 0
   END AS VALOR
  FROM pagamentos
 WHERE forma_pagamento IN ('CREDITO', 'DINHEIRO')
 GROUP BY DATA;

Eu não testei (até pq não tenho o MySQL instalado), mas é algo assim.
A cláusula IN considera todos os possíveis meios de pagamento e o case trata do caso específico do cartão.

Brilhante @AbelBueno, era exatamente o que precisava para resolver o meu problema. Eu já tinha tentado uns joins malucos, mas não tinha pensado no dinstinct. Sua lógica foi perfeita. A consulta ficou assim:

SELECT 
    datas.data,
    IF(credito.valores IS NULL, 0, credito.valores)
FROM
    (SELECT DISTINCT data
     FROM pagamentos) datas
LEFT JOIN
    (SELECT data, SUM(valor) valores
     FROM pagamentos
     WHERE forma_pagamento = 'CREDITO'
     GROUP BY data) credito 
ON datas.data = credito.data;

Fico muito feliz por existirem pessoas assim que compartilham o conhecimento com humildade e respeito pelas pessoas, sem esperar nada em troca. Parabéns e muito obrigado!

1 curtida

@darlan_machado esta sua consulta não funciona. Pelo que eu entendi naquelas pesquisas que eu fiz o motivo dela não executar é (me corrijam se estiver errado por favor) porque a engine do banco de dados executa o GROUP BY antes do SELECT ou seja não é possivel executar uma função de controle de fluxo em cada linha, se elas já estão agrupadas. Mas de qualquer forma obrigado por tentar.