技术开发 频道

使用CTE来实现一条查询丢失的数据行问题


【IT168技术文档】

  问题描述:PricesDaily表存有每天的价格数据,基本上是每天一条(除去周末两天和法定节假日没有)。
  现在问题是其中(以ASXCode和Date来判断)某天的数据丢失,有啥方法找到丢失这天的数据(返回丢失的ASXCode和Date)。

  PricesDaily原表数据如下:
ASXCode,Date,Price ------------------------------------- AAA 1999-01-04 00:00:00 2.5000 AAA 1999-01-05 00:00:00 2.4200 AAA 1999-01-06 00:00:00 2.4500 AAA 1999-01-07 00:00:00 2.5100 AAA 1999-01-08 00:00:00 2.5700 AAA 1999-01-11 00:00:00 2.6200 AAA 1999-01-12 00:00:00 2.7400 AAA 1999-01-13 00:00:00 2.6300 AAA 1999-01-14 00:00:00 2.6400 AAA 1999-01-15 00:00:00 2.7200 AAA 1999-01-19 00:00:00 2.6400 AAB 2004-09-24 00:00:00 .8400 AAB 2004-09-27 00:00:00 .8400 AAB 2004-09-28 00:00:00 .8300 AAB 2004-09-29 00:00:00 .8400 AAB 2004-09-30 00:00:00 .8300 AAB 2004-10-01 00:00:00 .8300 AAB 2004-10-04 00:00:00 .8000 AAB 2004-10-05 00:00:00 .8300 AAB 2004-10-07 00:00:00 .8300 AAB 2004-10-08 00:00:00 .7900
  上面原表中,有啥方法可以查出丢失了两条(周末两天和法定节假日除外):
  ASXCode = 'AAA',Date = '1999-01-18' 和 ASXCode = 'AAB',Date = '2004-10-06';
  只要返回丢失的ASXCode和Date。

  使用CTE解决方法:
use Test Declare @1 Table(ASXCode char(3),Date datetime,Price money) Insert Into @1 Select 'AAA', '1999-01-04 00:00:00', 2.5000 Union All Select 'AAA', '1999-01-05 00:00:00', 2.4200 Union All Select 'AAA', '1999-01-06 00:00:00', 2.4500 Union All Select 'AAA', '1999-01-07 00:00:00', 2.5100 Union All Select 'AAA', '1999-01-08 00:00:00', 2.5700 Union All Select 'AAA', '1999-01-11 00:00:00', 2.6200 Union All Select 'AAA', '1999-01-12 00:00:00', 2.7400 Union All Select 'AAA', '1999-01-13 00:00:00', 2.6300 Union All Select 'AAA', '1999-01-14 00:00:00', 2.6400 Union All Select 'AAA', '1999-01-15 00:00:00', 2.7200 Union All Select 'AAA', '1999-01-19 00:00:00', 2.6400 Union All Select 'AAB', '2004-09-24 00:00:00', .8400 Union All Select 'AAB', '2004-09-27 00:00:00', .8400 Union All Select 'AAB', '2004-09-28 00:00:00', .8300 Union All Select 'AAB', '2004-09-29 00:00:00', .8400 Union All Select 'AAB', '2004-09-30 00:00:00', .8300 Union All Select 'AAB', '2004-10-01 00:00:00', .8300 Union All Select 'AAB', '2004-10-04 00:00:00', .8000 Union All Select 'AAB', '2004-10-05 00:00:00', .8300 Union All Select 'AAB', '2004-10-07 00:00:00', .8300 Union All Select 'AAB', '2004-10-08 00:00:00', .7900 ;With T1 As ( Select ASXCode,Startdate=Min(Date),EndDate=Max(Date) From @1 Group By ASXCode ) ,T2 As ( Select ASXCode,Date=Startdate From T1 Union All Select a.ASXCode,Date=a.Date+1 From T2 a,T1 b Where a.ASXCode=b.ASXCode And a.Date<b.EndDate ) Select a.* From T2 a Left Outer Join @1 b On b.ASXCode=a.ASXCode And a.Date=b.Date Where b.Date Is null And Datename(dw,a.date) Not In('星期六','星期日') Option(Maxrecursion 0) --其他假日条件可以自由加入 /* (21 行受影响) ASXCode Date ------- ----------------------- AAB 2004-10-06 00:00:00.000 AAA 1999-01-18 00:00:00.000 (2 行受影响) */
  CTE默认可以递归100层,所以使用Option(Maxrecursion 0)参数,
  CTE目前最大可以32767层,从我们现实考虑(Select 32767/365.0=89.772602)可以查询89年的数据,已经够用了呵呵。
0
相关文章