使用SQL查询检查序列

时间:2009-04-29 15:06:02

标签: sql sql-server ms-access sequence

我有一个表订单,可以保存我们所有商店的所有订单。 我写了一个查询来检查每个商店的序列顺序。 它看起来像那样。

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

我可以查看此查询中是否存在所有订单。 web ordernumber是1 ... n。

中的数字

如何在不加入临时/不同表的情况下编写查询以查找丢失的订单?

4 个答案:

答案 0 :(得分:6)

您可以将表连接到自身以检测没有前一行的行:

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 :(得分:4)

我会创建一个“从1到n的所有整数”的辅助表(有关使用SQL Server函数的一些方法,请参阅http://www.sql-server-helper.com/functions/integer-table.aspx,但是因为它是你需要反复使用的东西我会无论如何,将它变成一个真正的表,并且使用任何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以了解与您类似的问题,“检测数字序列中的间隙”。

答案 2 :(得分:2)

如果你有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)

答案 3 :(得分:1)

如果您的数据库支持分析函数,那么您可以使用如下查询:

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号的数字。