SELECT displaying products except the results of another SELECT

Asked

Viewed 376 times

4

I have this SELECT that picks up the 6 best selling products:

SELECT IdProduto, SUM(QtdProdutoPedido) as QtdProdutoPedido FROM tb_pedidoproduto 
GROUP BY IdProduto ORDER BY QtdProdutoPedido DESC LIMIT 6

Wanted a SELECT showing all other registered products except those shown with the SELECT above. I tried to use NOT EXIST:

SELECT * FROM `tb_produto` WHERE NOT EXISTS 
   (SELECT IdProduto, SUM(QtdProdutoPedido) as QtdProdutoPedido FROM tb_pedidoproduto 
     GROUP BY IdProduto ORDER BY QtdProdutoPedido DESC LIMIT 6) 
&& IdCategoria = 2 ORDER BY IdProduto ASC

But I couldn’t put it together. If you have a way to do it in PHP it can also be.


I tried to use NOT EXISTS but it is bringing the results that does not exist in the table tb_pedidoproduto, I believe that the LIMIT is not working:

SELECT produto.IdProduto, produto.NomeProduto, produto.IdCategoria, produto.Imagem, 
produto.QtdMedida, produto.ValorProduto, produto.IdUnidadeMedida, produto.DescricaoProduto 
FROM tb_produto as produto WHERE produto.IdCategoria = '2' AND NOT EXISTS (
SELECT pedidoproduto.IdProduto, SUM(pedidoproduto.QtdProdutoPedido) as QtdProdutoPedido 
FROM tb_pedidoproduto as pedidoproduto
WHERE produto.IdCategoria = '2' 
AND produto.IdProduto = pedidoproduto.IdProduto 
GROUP BY pedidoproduto.IdProduto ORDER BY QtdProdutoPedido DESC LIMIT 6) 
ORDER BY produto.IdProduto ASC

Basically what I need is to subtract the results of the first SELECT from those of the second, I tried to make a SELECT using the operand "-" but it did not function either. Somebody help me plss . . .

  • SELECT * FROM tb_produto WHERE IdProduto NOT in (SELECT IdProduto, SUM(QtdProdutoPedido) as QtdProdutoPedido FROM tb_pedidoproduto GROUP BY IdProduto ORDER BY QtdProdutoPedido DESC LIMIT 6) && IdCategoria = 2 ORDER BY IdProduto ASC

  • " #1235 - This version of Mysql does not yet support 'LIMIT & IN/ALL/ANY/SOME subquery' " , gave zinaba man :^/

  • https://stackoverflow.com/questions/1519272/mysql-not-in-query

2 answers

3

You can get all results except the 6 BEST SELLERS using LIMIT two-parameter:

LIMIT 6,18446744073709551615

This will return in the query from the 7th record to the last.

inserir a descrição da imagem aqui

According to Mysql documentation:

To Retrieve all Rows from a Certain offset up to the end of the result set, you can use some large number for the Second Parameter. This statement retrieves all Rows from the 96th Row to the last.

SELECT * FROM tbl LIMIT 95,18446744073709551615;

Translation: to retrieve all records from a certain point until the end of the result, you can use a large number in the second parameter [...]

To sort the result by IdProduto, include , IdProduto after QtdProdutoPedido DESC:

SELECT IdProduto, SUM(QtdProdutoPedido) as QtdProdutoPedido FROM tb_pedidoproduto 
GROUP BY IdProduto ORDER BY
QtdProdutoPedido DESC, IdProduto
LIMIT 6,18446744073709551615
  • Thank you for sharing your knowledge. I was unaware of this valid alternative.

1

According to the documentation in Mysql version 5.7(current). There are some errors that apply only to subqueries. The error described by you in the commentary is one of them.

  • Syntax not supported in subquery:

    ERROR 1235 (ER_NOT_SUPPORTED_YET) SQLSTATE = 42000 Message = "This version of Mysql doesn’t yet support 'LIMIT & IN/ALL/ANY/SOME subquery'"

A script used as an example in the documentation is similar to yours:

SELECT * FROM t1 WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1)

In these cases use a task comparison attribute. Use the attribute that relates the two tables to optimize the query.

Your appointment would look like this:

SELECT * FROM tb_produto AS produto
WHERE
    NOT EXISTS(
        SELECT * FROM tb_pedidoproduto AS pedidoProduto
        WHERE
            pedidoProduto.IdCategoria = 2
                AND pedidoProduto.primaryKeyDaTabela IS NOT NULL
                AND pedidoProduto.IdProduto = produto.IdProduto
        GROUP BY pedidoProduto.IdProduto
        ORDER BY COUNT(pedidoProduto.QtdProdutoPedido) DESC
        LIMIT 5
    );

Note: I added the line AND pedidoProduto.primaryKeyDaTabela IS NOT NULL because primaryKeyDaTabela can be null and return false. As a consequence the count() will count all false together. This will be wrong information for the superiror script to make the decision which product it will bring. For this reason the solution was to add NOT NULL for the returns of primaryKeyDaTabela.

You can take a test and run the SELECT within the NOT EXISTS () separate. So you can check if any IdProduto return as null

Any doubt or error comments there

Browser other questions tagged

You are not signed in. Login or sign up in order to post.