1
resposta

Subconsulta ou múltiplos JOINS

Boa tarde!

Para a consulta "quais produtos foram vendidos ou não em um determinado mês" apenas optei por adicionar a quantidade.
E utilizando a subconsulta funcionou normalmente, ou seja, os produtos que não foram vendidos no mês 10 são listados como NULL já que foi utilizado o RIGHT JOIN com a tabela produtos:

SELECT pr.nome, x.id_pedido, x.id_produto, x.quantidade
FROM (
    SELECT i.id_pedido, i.id_produto, i.quantidade
      FROM pedidos AS p INNER JOIN itens_pedido AS i
      ON p.id = i.id_pedido
      WHERE STRFTIME ('%m', p.data_hora_pedido) = '10'
    ) AS x
RIGHT JOIN produtos AS pr
ON pr.id = x.id_produto
ORDER BY pr.nome;

Tentei replicar a mesma consulta utilizando múltiplos JOINS, e desta forma, os produtos que não foram vendidos no mês 10 não são listados.

SELECT pr.nome, i.id_pedido, i.id_produto, SUM (i.quantidade) AS 'quantidade'
FROM pedidos AS p INNER JOIN itens_pedido AS i
ON p.id = i.id_pedido
RIGHT JOIN produtos AS pr
ON pr.id = i.id_produto
WHERE STRFTIME('%m', p.data_hora_pedido) = '10'
GROUP BY pr.nome
ORDER BY pr.nome;

A lógica aparentemente é a mesma, mas não consegui identificar porque as consultas apresentam resultados diferentes.

1 resposta

Oi Luiz, tudo bem? 😊

Agradeço por compartilhar seu código e a sua dúvida! 💪

A diferença nos resultados ocorre devido à ordem em que as operações são realizadas e como o WHERE interage com o RIGHT JOIN.

Na sua primeira consulta, a subconsulta restringe os dados de pedidos e itens_pedido ANTES de realizar o RIGHT JOIN com a tabela produtos. Isso garante que todos os produtos sejam considerados, e aqueles que não têm correspondência nos pedidos de outubro recebem valores NULL nas colunas referentes aos pedidos.

Na segunda consulta, o filtro WHERE é aplicado APÓS o JOIN. Isso significa que ele remove as linhas onde p.data_hora_pedido não corresponde a outubro, eliminando os produtos que não foram vendidos naquele mês ANTES da agregação pelo GROUP BY.

Para obter o resultado desejado com múltiplos JOINs, você pode ajustar a consulta para garantir que o filtro de mês seja aplicado corretamente sem eliminar os produtos que não foram vendidos em outubro. Uma forma de fazer isso é mover a condição do WHERE para dentro de um LEFT JOIN com a tabela de pedidos, e então usar um RIGHT JOIN com a tabela de produtos.

Aqui está uma sugestão de como você pode modificar sua segunda consulta:

SELECT 
    pr.nome,
    i.id_pedido,
    i.id_produto,
    SUM(CASE WHEN STRFTIME('%m', p.data_hora_pedido) = '10' THEN i.quantidade ELSE 0 END) AS 'quantidade'
FROM produtos AS pr
LEFT JOIN itens_pedido AS i ON pr.id = i.id_produto
LEFT JOIN pedidos AS p ON i.id_pedido = p.id
GROUP BY pr.nome
ORDER BY pr.nome;

Nessa consulta, todos os produtos são mantidos devido ao LEFT JOIN com itens_pedido e pedidos. A condição de filtro do mês é aplicada apenas ao calcular a soma da quantidade, garantindo que os produtos sem vendas em outubro ainda apareçam no resultado com quantidade zero.

🎓 Para saber mais:

Espero ter ajudado a esclarecer sua dúvida! 🤔