SQLクエリを使用したシーケンスの確認
-
03-07-2019 - |
質問
すべてのストアからのすべての注文を保持するテーブル注文があります。 各店舗の順序を確認するクエリを作成しました。 そのように見えます。
select WebStoreID, min(webordernumber), max(webordernumber), count(webordernumber)
from orders
where ordertype = 'WEB'
group by WebStoreID
このクエリですべての注文が存在することを確認できます。ウェブ注文番号は1 ... nからの番号です。
一時/別のテーブルに参加せずに欠落している注文を見つけるためのクエリを作成するにはどうすればよいですか?
解決
テーブル自体を結合して、前の行がない行を検出できます。
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
これにより、1 ... nシーケンスのギャップが検出されますが、重複は検出されません。
他のヒント
「1〜nのすべての整数」という補助テーブルを作成します。 ( http://www.sql-server-helper.com/を参照してください。 functions / integer-table.aspx を使用してSQL Server関数で作成する方法がいくつかありますが、何度も必要になるので、とにかく実際のテーブルに作成し、SQLエンジンで作成しますそれを簡単に一度だけ)、ネストされたクエリを使用して、 SELECT value FROM integers WHERE value NOT IN(SELECT webordernumber FROM orders)
&amp; c。 http://www.sqlmag.com/Article/ArticleID/99797/も参照してください。 sql_server_99797.html に似た問題については、「一連の数字のギャップを検出する」」。
rank()関数はあるがlag()関数(つまりSQL Server)はない場合、これを使用できます( http://www.sqlmonster.com/Uwe/Forum.aspx/sql-server-programming / 10594 / Return-gaps-in-a-sequence ):
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
...または、「外部制限」を含めるには:
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)
データベースが分析機能をサポートしている場合、次のようなクエリを使用できます。
select prev+1, curr-1 from
( select webordernumber curr,
coalesce (lag(webordernumber) over (order by webordernumber), 0) prev
from orders
)
where prev != curr-1;
出力にはギャップが表示されます。例:
prev+1 curr-1
------ ------
3 7
3から7までの数字が欠けていることを意味します。