lista de um SELECT de duas tabelas sem relacionamento ou chave estrangeira

1. lista de um SELECT de duas tabelas sem relacionamento ou chave estrangeira

Jean de Sousa
JeanzinRJ

(usa Debian)

Enviado em 05/02/2018 - 15:45h

Salve, galera!



Queria tirar uma dúvida com vocês. Eu tenho duas tabelas uma de venda e uma de despesas.

Gostaria de criar um SELECT para formar uma lista por ordem de transação seja de venda ou de despesa. porém essas tabelas não tem nenhuma relacão.

tentei os seguintes SQLs



SELECT * FROM `tab_compras`,`tab_despesa` WHERE tab_compras.time_venda LIKE '2018-02%' AND tab_despesa.datetime_despesa LIKE '2018-02%'



porém o resultado sai duplicado



tabela venda



ID | venda      | valor | data_venda

1   |   item_1 | 100    | 2017-02-01

2   |   item_2 | 120    | 2017-02-02

3   |   item_3 | 200    | 2017-02-03



tabela despesa

ID | despesa      | valor | data_venda

1   |   despesa_1 | 10    | 2017-02-01

2   |   despesa_2 | 90    | 2017-02-02

3   |   despesa_3 | 65    | 2017-02-03



resultado esperado



lista:



atividade   | valor   | data

item_1       |  100    | 2017-02-01

despesa_1| 10       | 2017-02-01

despesa_2| 90       | 2017-02-02

item_2       | 120     | 2017-02-02





  


2. Re: lista de um SELECT de duas tabelas sem relacionamento ou chave estrangeira

Perfil removido
removido

(usa Nenhuma)

Enviado em 05/02/2018 - 16:34h

Tenta algo assim (modifique conforme a necessidade):

SELECT ID, atividade, valor, data_venda FROM (
SELECT ID, venda AS atividade, valor, data_venda FROM `tab_compras` WHERE tab_compras.time_venda LIKE '2018-02%'
UNION
SELECT ID, despesa AS atividade, valor, data_venda FROM `tab_despesa` WHERE tab_despesa.datetime_despesa LIKE '2018-02%'
) ORDER BY data_venda ASC



3. Re: lista de um SELECT de duas tabelas sem relacionamento ou chave estrangeira

Hugo Cerqueira
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






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts