List two distinct tables and filter by date MySQL - PHP

1

My problem is that I need to list values from two distinct tables, and I'm using a filter to add conditions in the query. For example:

if(!empty($mes_especifico)) {
   $sql .= "AND YEAR(d.data_pagamento) = :ano AND MONTH(d.data_pagamento) = :mes ";
   $insertData[":ano"] = $ano;
   $insertData[":mes"] = $mes;
}

I wanted to know how to join in the same query and list the tables and sort by number of plots.

Tables: link

Separated:

SELECT FORMAT(r.valor_receita,2,'de_DE') AS valor_receita,
       DATE_FORMAT(r.data_vencimento, '%d/%m/%Y') AS data_vencimento,
       r.recebido,
       DATE_FORMAT(r.data_recebimento, '%d/%m/%Y') AS data_recebimento,
       r.tipo_repeticao,
       r.parcelas,
       r.numero_parcela,
       r.recorrente,
       r.observacoes,
       tr.tipo_receita,
       re.tipo_recebimento
FROM receitas AS r
INNER JOIN tipo_receita AS tr ON r.id_tipo_receita = tr.id_tipo_receita
INNER JOIN tipo_recebimento AS re ON r.id_tipo_recebimento = re.id_tipo_recebimento
WHERE r.id_usuario = 1;

SELECT FORMAT(d.valor_despesa,2,'de_DE') AS valor_despesa,
       DATE_FORMAT(d.data_vencimento, '%d/%m/%Y') AS data_vencimento,
       d.pago,
       DATE_FORMAT(d.data_pagamento, '%d/%m/%Y') AS data_pagamento,
       d.importante,
       d.tipo_repeticao,
       d.parcelas,
       d.numero_parcela,
       d.recorrente,
       d.observacoes,
       td.tipo_despesa,
       c.nome_categoria,
       tp.tipo_pagamento
FROM despesas AS d
INNER JOIN tipo_despesa AS td ON d.id_tipo_despesa = td.id_tipo_despesa
INNER JOIN tipo_pagamento AS tp ON d.id_tipo_pagamento = tp.id_tipo_pagamento
INNER JOIN categorias AS c ON td.id_categoria = c.id_categoria
WHERE d.id_usuario = 1;
    
asked by anonymous 21.06.2017 / 20:32

2 answers

2

If all columns are of the same type, just use UNION :

SELECT FORMAT(r.valor_receita,2,'de_DE') AS valor_receita,
       DATE_FORMAT(r.data_vencimento, '%d/%m/%Y') AS data_vencimento,
       r.recebido,
       DATE_FORMAT(r.data_recebimento, '%d/%m/%Y') AS data_recebimento,
       null as importante,
       r.tipo_repeticao,
       r.parcelas,
       r.numero_parcela,
       r.recorrente,
       r.observacoes,
       tr.tipo_receita,
       null as categoria,
       re.tipo_recebimento
FROM receitas AS r
INNER JOIN tipo_receita AS tr ON r.id_tipo_receita = tr.id_tipo_receita
INNER JOIN tipo_recebimento AS re ON r.id_tipo_recebimento = re.id_tipo_recebimento
WHERE r.id_usuario = 1

UNION 

SELECT FORMAT(d.valor_despesa,2,'de_DE') AS valor_despesa,
       DATE_FORMAT(d.data_vencimento, '%d/%m/%Y') AS data_vencimento,
       d.pago,
       DATE_FORMAT(d.data_pagamento, '%d/%m/%Y') AS data_pagamento,
       d.importante,
       d.tipo_repeticao,
       d.parcelas,
       d.numero_parcela,
       d.recorrente,
       d.observacoes,
       td.tipo_despesa,
       c.nome_categoria,
       tp.tipo_pagamento
FROM despesas AS d
INNER JOIN tipo_despesa AS td ON d.id_tipo_despesa = td.id_tipo_despesa
INNER JOIN tipo_pagamento AS tp ON d.id_tipo_pagamento = tp.id_tipo_pagamento
INNER JOIN categorias AS c ON td.id_categoria = c.id_categoria
WHERE d.id_usuario = 1;

Obs. Use null to hit the missing columns in the other table, so you can execute the command.

If there are type conflicts, you can convert the values.

    
21.06.2017 / 20:42
2

The solution already presented is right, you should use UNION same, equating field types in both SELECTs , consider that the fields exist in both "SELECTs", when it does not exist, you create them as " NULL "and gives the name to it with the" AS ". On the other hand, it is good to give the identical name to the fields so that they are recognized, so you will not have the problem you say you have. Based on this, I've remodeled your script as follows:

SELECT valor,
       data_vencimento,
       estatus,
       data_movimento,
       importante,
       tipo_repeticao,
       parcelas,
       num_parcelas,
       recorrente,
       observacoes,
       tipo_origem,
       categoria,
       tipo_movto,
       identifica_origem
  FROM (
        SELECT FORMAT(r.valor_receita,2,'de_DE') AS valor,
               DATE_FORMAT(r.data_vencimento, '%d/%m/%Y') AS data_vencimento,
               r.recebido as estatus,
               DATE_FORMAT(r.data_recebimento, '%d/%m/%Y') AS data_movimento,
               NULL as importante,
               r.tipo_repeticao as tipo_repeticao,
               r.parcelas as parcelas,
               r.numero_parcela as num_parcelas,
               r.recorrente as recorrente,
               r.observacoes as observacoes,
               tr.tipo_receita as tipo_origem,
               NULL as categoria,
               re.tipo_recebimento as tipo_movto,
               'Receita' AS identifica_origem
          FROM receitas AS r
               INNER JOIN tipo_receita AS tr ON (r.id_tipo_receita = tr.id_tipo_receita)
               INNER JOIN tipo_recebimento AS re ON (r.id_tipo_recebimento = re.id_tipo_recebimento)
        WHERE r.id_usuario = 1
        UNION 
        SELECT FORMAT(d.valor_despesa,2,'de_DE') AS valor,
               DATE_FORMAT(d.data_vencimento, '%d/%m/%Y') AS data_vencimento,
               d.pago AS estatus,
               DATE_FORMAT(d.data_pagamento, '%d/%m/%Y') AS data_movimento
               d.importante AS importante,
               d.tipo_repeticao as tipo_repeticao,
               d.parcelas as parcelas,
               d.numero_parcela as num_parcelas,
               d.recorrente  as recorrente,
               d.observacoes as observacoes,
               td.tipo_despesa as tipo_origem,
               c.nome_categoria as categoria,
               tp.tipo_pagamento as tipo_movto,
               'Despesa' AS identifica_origem
          FROM despesas AS d
               INNER JOIN tipo_despesa AS td ON (d.id_tipo_despesa = td.id_tipo_despesa)
               INNER JOIN tipo_pagamento AS tp ON (d.id_tipo_pagamento = tp.id_tipo_pagamento)
               INNER JOIN categorias AS c ON (td.id_categoria = c.id_categoria)
         WHERE d.id_usuario = 1
        ) AS origem
       ) AS origem
 WHERE (tipo_origem = 'Água')
 ORDER BY data_movimento

See that the SELECTs I left them in parentheses, as FROM of SELECT , which is the name of Origem , from there, I can filter, order, finally, results from UNION as you see fit, as select normal. The code may seem long, but worth wasting time and making it look nice, so if needed, it will make it easier to understand and maintain later.

    
21.06.2017 / 21:38