Überprüfen Sequenz mit SQL-Abfrage
-
03-07-2019 - |
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?
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.