Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL :découvrez les ID de commande manquants

Voici une autre solution pour ce faire :

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;

Cela devrait vous donner le orders_id s :

ID
1001
1002
1005
1006
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1021
1022
1023
1024

Démo SQL Fiddle

Notez que : J'ai créé un TEMP table avec des valeurs de 0 à 9, afin de l'utiliser pour générer une table d'ancrage contenant des valeurs de 1 à 10000 au lieu de la boucle while que vous aviez dans la requête que vous avez postée. Vous pouvez contrôler les valeurs de ce tableau en fonction des valeurs de votre tableau. Si vous aviez des valeurs supérieures à 10000 CROSS JOIN le TEMP table une fois de plus.

Mise à jour : Si le orders_id est de type de données varchar il suffit de le convertir en INTEGER comme ç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;

Démo SQL Fiddle mise à jour