2009-04-29 182 views
1

我有一个表格命令可以保持我们所有商店的所有订单。 我写了一个查询来检查每个商店的顺序订单。 看起来像那样。使用SQL查询检查序列

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

我可以检查所有订单是否与此查询一起存在。网上订单号是1 ... n之间的数字。

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

+0

这是很难选择的数据,实际上是不存在的。 – 2009-04-29 15:20:01

+0

从评论中可以清楚地看到,你在这里对SQL Server运行。你真的应该在你的问题中说过,或者用标签来表示它([SQL]是SQL问题的通用标记,而不是SQL Server)。 – 2011-02-23 23:03:28

回答

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序列的空白,但它不会检测重复。

4

我会制作一个“从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) & c。另请参阅http://www.sqlmag.com/Article/ArticleID/99797/sql_server_99797.html,查看与您的问题类似的问题,“检测数字序列中的空白”。

+0

+感谢您的好链接。 – THEn 2009-04-29 15:26:07

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。

+0

谢谢。什么是nvl?我无法在MSSQL上找到它? – THEn 2009-04-29 15:20:21

2

如果你有秩()函数,而不是滞后()函数(换句话说,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)