Frage

Ich habe eine Tabelle Bestellungen, die alle um von allen unseren Geschäften halten. Ich schrieb eine Abfrage, um die Sequenz Aufträge für jedes Geschäft zu überprüfen. Es sieht so aus.

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

ich kann sie alle Aufträge vorhanden sind, mit dieser Abfrage. Web-Bestellnummer ist die Nummer 1 ... n.

Wie kann ich Abfrage schreiben Aufträge finden fehlt ohne temporäre / andere Tabelle beizutreten?

War es hilfreich?

Lösung

Sie können in der Tabelle auf sich selbst verbinden Reihen zu erkennen, die keine vorhergehende Zeile haben:

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

Dies würde erkennen Lücken in der 1 ... n-Sequenz, aber es würde Duplikate nicht erkennen.

Andere Tipps

Ich würde eine Hilfstabelle "alle Zahlen von 1 bis n" (siehe machen http://www.sql-server-helper.com/functions/integer-table.aspx für einige Möglichkeiten, es mit einer SQL Server-Funktion zu machen, aber da es etwas ist, benötigen Sie immer und über ich es zu einem echten Tisch sowieso machen würde, und mit jeder SQL-Engine ist es einfach, das zu machen, einmal nur) dann eine verschachtelte Abfrage, SELECT value FROM integers WHERE value NOT IN (SELECT webordernumber FROM orders) & c verwenden. Auch finden Sie unter http://www.sqlmag.com/Article/ArticleID/99797/ sql_server_99797.html für ein ähnliches Problem wie bei Ihnen, „Erfassen Lücken in einer Folge von Zahlen.“

Wenn Sie die Rang () Funktion haben, aber nicht die Verzögerung () Funktion (in anderen Worten, SQL Server), können Sie diese verwenden können (vorgeschlagen von http://www.sqlmonster.com/Uwe/Forum.aspx/sql-server-programming / 10594 / Return-Lücken-in-a-Sequenz ):

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

... oder, schließt die "Außengrenzen":

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)

Wenn Ihre Datenbank unterstützt analytische Funktionen, dann können Sie eine Abfrage so etwas wie verwenden:

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

Der Ausgang wird die Lücken z.

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

würde bedeuten, dass Zahlen 3 bis einschließlich 7 fehlen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top