Domanda

Ho un ordine da tavolo che conserva tutti gli ordini da tutti i nostri negozi. Ho scritto una query per verificare gli ordini di sequenza per ciascun negozio. Sembra così.

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

Posso verificare che tutti gli ordini siano presenti con questa query. il numero dell'ordine web è il numero da 1 ... n.

Come posso scrivere una query per trovare gli ordini mancanti senza unirmi a una tabella temporanea / diversa?

È stato utile?

Soluzione

È possibile unire la tabella su se stessa per rilevare le righe che non hanno una riga precedente:

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

Questo rileverebbe lacune nella sequenza 1 ... n, ma non rileverebbe duplicati.

Altri suggerimenti

Vorrei fare una tabella ausiliaria di " tutti gli interi da 1 a n " (vedi http://www.sql-server-helper.com/ funzioni / integer-table.aspx per alcuni modi per farlo con una funzione di SQL Server, ma dato che è qualcosa di cui avrai bisogno più volte, lo trasformerei comunque in una vera tabella, e con qualsiasi motore SQL è facile farlo, solo una volta) quindi usa una query nidificata, SELEZIONA valore DA numeri interi DOVE valore NON IN (SELEZIONA webordernumber DA ordini) & amp; c. Vedi anche http://www.sqlmag.com/Article/ArticleID/99797/ sql_server_99797.html per un problema simile al tuo, "rilevamento di spazi vuoti in una sequenza di numeri".

Se hai la funzione rank () ma non la funzione lag () (in altre parole, SQL Server), puoi usarla (suggerita da http://www.sqlmonster.com/Uwe/Forum.aspx/sql-server-programming / 10594 / Return-gap-in-a-sequenza ):

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

... oppure, per includere i "limiti esterni":

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)

Se il tuo database supporta funzioni analitiche, puoi utilizzare una query simile a:

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

L'output mostrerà le lacune, ad esempio

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

significherebbe che mancano i numeri da 3 a 7 inclusi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top