Question

J'ai une commande de table qui conserve toutes les commandes de tous nos magasins. J'ai écrit une requête pour vérifier les ordres de séquence pour chaque magasin. Ça ressemble à ça.

select WebStoreID, min(webordernumber), max(webordernumber), count(webordernumber) 
from orders
where ordertype = 'WEB' 
group by WebStoreID

Je peux vérifier que toutes les commandes sont présentes avec cette requête. le numéro d'ordre Web est le numéro 1 ... n.

Comment puis-je écrire une requête pour trouver les commandes manquantes sans rejoindre la table temporaire / différente?

Était-ce utile?

La solution

Vous pouvez joindre la table sur elle-même pour détecter les lignes qui n'ont pas de ligne précédente:

select cur.*
from orders cur
left join orders prev 
    on cur.webordernumber = prev.webordernumber + 1
    and cur.webstoreid = prev.webstoreid
where cur.webordernumber <> 1
and prev.webordernumer is null

Cela permettrait de détecter les lacunes dans la séquence 1 ... n, mais pas les doublons.

Autres conseils

Je ferais une table auxiliaire de "tous les entiers de 1 à n" (voir http://www.sql-server-helper.com/ functions / integer-table.aspx pour certaines manières de le créer avec une fonction SQL Server, mais comme c'est quelque chose dont vous aurez besoin encore et encore, j'en ferais de toute façon une vraie table, et avec n'importe quel moteur SQL, c'est facile à faire, juste une fois) puis utilisez une requête imbriquée, SELECT valeur FROM nombres entiers WHERE valeur NOT IN (SELECT ordre Web ordre FROM ordre) & amp; c. Voir également http://www.sqlmag.com/Article/Article/ArticleID/99797/ sql_server_99797.html pour un problème similaire au vôtre, "détection des lacunes dans une séquence de chiffres".

Si vous avez la fonction rank () mais pas la fonction lag () (en d'autres termes, SQL Server), vous pouvez l'utiliser (suggéré par http://www.sqlmonster.com/Uwe/Forum.aspx/sql-server-programming / 10594 / Retour dans la séquence ):

create table test_gaps_in_sequence (x int)
insert into test_gaps_in_sequence values ( 1 )
insert into test_gaps_in_sequence values ( 2 )
insert into test_gaps_in_sequence values ( 4 )
insert into test_gaps_in_sequence values ( 5 )
insert into test_gaps_in_sequence values ( 8 )
insert into test_gaps_in_sequence values ( 9 )
insert into test_gaps_in_sequence values ( 12)
insert into test_gaps_in_sequence values ( 13)
insert into test_gaps_in_sequence values ( 14)
insert into test_gaps_in_sequence values ( 29)

...

 select lower_bound
         , upper_bound
      from (select upper_bound
                 , rank () over (order by upper_bound) - 1 as upper_rank
              from (SELECT x+n as upper_bound
                      from test_gaps_in_sequence
                         , (SELECT 0 n
                            UNION
                            SELECT -1
                           ) T
                     GROUP BY x+n
                    HAVING MAX(n) = -1
                    ) upper_1
            ) upper_2
         , (select lower_bound
                 , rank () over (order by lower_bound) as lower_rank
              from (SELECT x+n as lower_bound
                      from test_gaps_in_sequence
                         , (SELECT 0 n
                            UNION
                            SELECT 1
                           ) T
                     GROUP BY x+n
                    HAVING MIN(n) = 1
                    ) lower_1
            ) lower_2
      where upper_2.upper_rank = lower_2.lower_rank
      order by lower_bound

... ou, pour inclure les "limites extérieures":

select lower_bound
     , upper_bound
  from (select upper_bound
             , rank () over (order by upper_bound) - 1 as upper_rank
          from (SELECT x+n as upper_bound
                  from test_gaps_in_sequence
                     , (SELECT 0 n
                        UNION
                        SELECT -1
                       ) T
                 GROUP BY x+n
                HAVING MAX(n) = -1
                ) upper_1
        ) upper_2
   full join (select lower_bound
             , rank () over (order by lower_bound) as lower_rank
          from (SELECT x+n as lower_bound
                  from test_gaps_in_sequence
                     , (SELECT 0 n
                        UNION
                        SELECT 1
                       ) T
                 GROUP BY x+n
                HAVING MIN(n) = 1
                ) lower_1
        ) lower_2
   on upper_2.upper_rank  = lower_2.lower_rank
     order by coalesce (lower_bound, upper_bound)

Si votre base de données prend en charge les fonctions analytiques, vous pouvez utiliser une requête du type:

select prev+1, curr-1 from
( select webordernumber curr,
         coalesce (lag(webordernumber) over (order by webordernumber), 0) prev
  from   orders
)
where prev != curr-1;

La sortie montrera les lacunes, par exemple.

prev+1 curr-1
------ ------
     3      7

signifierait que les numéros 3 à 7 inclus sont manquants.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top