Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL:descubra IDs de pedidos ausentes


Aqui está outra solução para fazer isso:
CREATE TABLE TEMP 
(n int);
INSERT INTO Temp VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);

SET @maxid = (SELECT MAX(orders_id) FROM orders);

SELECT     s.id 
FROM
(
    SELECT id
    FROM
    (
       SELECT t4.n * 1000 + t3.n * 100 + t2.n * 10 + t1.n + 1 AS id
       FROM         TEMP AS t1
       CROSS JOIN TEMP AS t2
       CROSS JOIN TEMP AS t3
       CROSS JOIN TEMP AS t4
    ) t 
    WHERE id BETWEEN 1000 AND @maxid
) s 
LEFT JOIN orders t ON s.id = t.`orders_id` 
WHERE t.`orders_id` IS NULL;

Isso deve fornecer o orders_id s:
ID
1001
1002
1005
1006
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1021
1022
1023
1024

Demonstração do SQL Fiddle


Observe que: Eu criei um TEMP table com valores de 0 a 9, para usar para gerar uma tabela âncora contendo valores de 1 a 10000 em vez do loop while que você tinha na consulta que você postou. Você pode controlar os valores desta tabela dependendo dos valores em sua tabela. Se você tiver valores que excedam 10.000 CROSS JOIN a TEMP mesa mais uma vez.

Atualização: Se o orders_id é do tipo de dados varchar apenas converta para INTEGER igual a:
SELECT     s.id 
FROM
(
    SELECT id
    FROM
    (
       SELECT t4.n * 1000 + t3.n * 100 + t2.n * 10 + t1.n + 1 AS id
       FROM         TEMP AS t1
       CROSS JOIN TEMP AS t2
       CROSS JOIN TEMP AS t3
       CROSS JOIN TEMP AS t4
  ) t WHERE id between 1000 AND @maxid
) s 
LEFT JOIN
(
    SELECT CONVERT(orders_id, UNSIGNED INTEGER) AS orders_id 
    FROM orders
) t ON s.id = t.`orders_id` 
WHERE t.`orders_id` IS NULL;

Demonstração do SQL Fiddle atualizada