hrcerq
(usa Outra)
Enviado em 05/02/2018 - 21:43h
Caro Jean,
Antes de falar sobre o problema da duplicação em específico, acho importante mencionar que as tabelas tem relação sim: o tempo. Essa é uma relação muito importante, embora também muito subestimada. Ela permite, na pior das hipóteses, estabelecer correlações que ajudam a fazer inferências. O tempo é uma informação fundamental em análises, porque contextualiza a informação que você está avaliando.
Dito isto, vamos ao aspecto técnico do problema:
A cláusula SELECT pode usar o curinga (*) como facilidade para não ter que digitar campo a campo. Mas isso tem um preço: quando esse curinga é expandido, ele é substituído por todos os campos de todas as tabelas consultadas, mesmo que haja campos repetidos entre elas: em geral o interpretador não tem como adivinhar que esses campos são de fato idênticos, porque podem ser apenas colunas diferentes com nomes em comum.
Por isso, para evitar a duplicação, você precisa especificar os campos um a um. Embora isso seja mais trabalhoso, te dá total controle sobre o resultado. Além disso, você quer tratar a venda e a despesa como valores de um mesmo tipo (devem ser agrupados em uma mesma coluna). Para conseguir isso, precisa fazer a união das colunas (cláusula UNION), quando o que está fazendo nessa consulta é uma junção (JOIN).
A maneira como você estruturou a cláusula FROM implicitamente aplica um cross join entre as tabelas, gerando produto cartesiano, o que não é o seu objetivo. Toda vez que você consulta mais de uma tabela e não especifica uma regra de junção, automaticamente o cross join é feito. Para fazer a união das colunas e gerar o resultado esperado, você precisa, portanto, criar duas consultas que tenham o mesmo tipo de saída (mesmo número de colunas, sendo os tipos de dados entre elas correspondentes entre si).
O exemplo a seguir mostra como isso pode ser feito:
Obs.: No meu exemplo estou considerando duas tabelas com as seguintes estruturas (parecidas com as suas):
Tabela de vendas (tab_venda) -> (id, venda, valor, data_venda)
Tabela de despesas (tab_despesa) -> (id, despesa, valor, data_despesa)
Verifique no seu caso os nomes das tabelas e colunas, mas o princípio é o mesmo:
SELECT
/* Note que usei um "alias" pra exibir venda
com o nome de atividade e data_venda com o
nome de data. */
venda as atividade,
valor,
data_venda as data
FROM tab_venda
WHERE data_venda LIKE '2018-02%'
UNION
SELECT
/* Na segunda consulta os "alias" são desnecessários
pois o nome usado é o do primeiro SELECT, mas usei
mesmo assim por questões de boa prática. */
despesa as atividade,
valor,
data_despesa as data
FROM tab_despesa
WHERE data_despesa LIKE '2018-02%'
;
Lembre-se: os tipos dos campos devem ser iguais nas duas consultas (veja se as datas não diferem, como uma sendo date e a outra datetime por exemplo).
O código ainda pode ficar melhor, se você fatorá-lo, veja:
/* A cláusula WITH encapsula uma consulta
como se fosse uma tabela. */
WITH vendas as
(SELECT
venda as atividade,
valor,
data_venda as data
FROM tab_venda),
despesas as
(SELECT
despesa as atividade,
valor,
data_despesa as data
FROM tab_despesa),
atividades as
(SELECT * FROM vendas UNION SELECT * FROM despesas)
SELECT * FROM atividades
WHERE data LIKE '2018-02%'
/* Aqui você só precisa informar a data uma vez. */
;
---
Atenciosamente,
Hugo Cerqueira