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

6 respostas Resolvido
C

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:

6 Respostas

D

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.

C

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 ?

A
Solucao aceita

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).

D
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.

C

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!

C

@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.

Criado 20 de junho de 2018
Ultima resposta 21 de jun. de 2018
Respostas 6
Participantes 3