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)
&씨. 또한 참조하십시오 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 포괄적 인 숫자가 누락되었음을 의미합니다.