problems with distinct in mysql

3

I have a select where I have to sort it by field 'qtd' The problem is that I have this field different, and I need the products not to be repeated.

The 'a.id' field stores the product code, ie it can not be repeated. Does anyone know how to solve this?

The 'b.qtd' field must be the sum of the two UNION tables.

Follow my select:

SELECT 
        DISTINCT a.id, 
        a.unidade, 
        a.posicao, 
        a.nome, 
        a.peso, 
        sum(b.qtd) quant 
    FROM 
        produtos a, 
        produtos_pedidos b 
    WHERE 
        a.id = b.id_produto 
        and b.id_pedido IN (3,2) 
    GROUP BY 
        a.id, 
        a.unidade, 
        a.posicao, 
        a.nome, 
        a.peso 

    UNION

    SELECT 
        DISTINCT c.id, 
        c.unidade, 
        c.posicao, 
        c.nome, 
        c.peso, 
        sum(d.qtd) quant 
    FROM 
        produtos c, 
        pedidos_barganha d 
    WHERE 
        c.id = d.id_produto 
        and d.id_pedido IN (3,2) 
    GROUP BY 
        c.id, 
        c.unidade, 
        c.posicao, 
        c.nome, 
        c.peso
    ORDER BY quant DESC
    
asked by anonymous 13.02.2017 / 18:35

3 answers

5

Your problem is that you have 2 tables with different information and you want to add them together. Your solution might work, but it will take a little time.

As a workaround I might suggest using a temporary table, which can be much simpler to use, while keeping the code legible.

CREATE TEMPORARY TABLE resultados (
  id_produto INT NOT NULL,
  qtd INT NOT NULL
);

INSERT INTO resultados(id_produto, qtd)
SELECT
  A.id,
  SUM(B.qtd)
FROM produtos AS A
INNER JOIN produtos_pedidos AS B
  ON (A.id = B.id_produto)
WHERE B.id_pedido IN (3,2) 
GROUP BY A.id;

INSERT INTO resultados(id_produto, qtd)
SELECT
  A.id,
  SUM(B.qtd)
FROM produtos AS A
INNER JOIN pedidos_barganha AS B
  ON (A.id = B.id_produto)
WHERE B.id_pedido IN (3,2) 
GROUP BY A.id;

/* ADICIONA UM INDICE PARA MELHORAR A CONSULTA */
ALTER TABLE resultados ADD KEY 'indice_temporario_01' (id_produto);

SELECT
  A.id_produto,
  SUM(A.qtd) AS QUANTIDADE,
  B.unidade, 
  B.posicao, 
  B.nome, 
  B.peso
FROM resultados AS A
INNER JOIN produtos AS B
  ON (A.id_produto = B.id)
GROUP BY A.id_produto
ORDER BY QUANTIDADE;

Note : I am considering both the product and its quantity are integers. Change the table creation to the correct data types if needed.

This query will bring up the sum of the tables of produtos_pedido and pedidos_barganha .

An important detail : I understand that the id column of the produtos table is a unique key. For this reason, there is no need to put the remaining columns in the GROUP BY clause.

One last performance tip : If you can, you can still change the temporary table creation to use a faster engine like MYISAM instead of InnoDb pattern. p>     

13.02.2017 / 20:54
5

Doing a JOIN between produtos and a union of produtos_pedidos should satisfy this. Something like this:

SELECT
  a.id,
  a.unidade,
  a.posicao,
  a.nome,
  a.peso,
  sum(d.qtd) quant
FROM
 produtos a JOIN
(
 SELECT b.id_produto, b.qtd
 FROM produtos_pedidos b
 WHERE b.id_pedido IN (3,2)

 UNION ALL

 SELECT c.id_produto, c.qtd
 FROM pedidos_barganha c 
 WHERE c.id_pedido IN (3,2)
) d ON a.id = d.id_produto
GROUP BY  
  a.id,
  a.unidade,
  a.posicao,
  a.nome,
  a.peso
ORDER BY quant DESC
    
13.02.2017 / 19:18
2

So friend, did you try with subqueries? Something like this:

SELECT DISTINCT a.id, 
    a.unidade, 
    a.posicao, 
    a.nome, 
    a.peso, 
    sum(b.qtd) quant
FROM ( 
    (SELECT 
        a.id, 
        a.unidade, 
        a.posicao, 
        a.nome, 
        a.peso, 
        sum(b.qtd) quant 
    FROM 
        produtos a, 
        produtos_pedidos b 
    WHERE 
        a.id = b.id_produto 
        and b.id_pedido IN (3,2) 
    GROUP BY 
        a.id, 
        a.unidade, 
        a.posicao, 
        a.nome, 
        a.peso

    UNION

    SELECT 
        c.id, 
        c.unidade, 
        c.posicao, 
        c.nome, 
        c.peso, 
        sum(d.qtd) quant 
    FROM 
        produtos c, 
        pedidos_barganha d 
    WHERE 
        c.id = d.id_produto 
        and d.id_pedido IN (3,2) 
    GROUP BY 
        c.id, 
        c.unidade, 
        c.posicao, 
        c.nome, 
        c.peso
    ORDER BY quant DESC) as tbl
)

In this way you would apply DISTINCT in the final results and not in each individual table.

UPDATE: I made a change in the code, see if it works, I put the aliases for each table up there

UPDATE 2: New change in code, reduced to virtual table only. Try to check now

    
13.02.2017 / 19:03