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


    问题描述: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年的数据,已经够用了呵呵。


  • 相关阅读:
    [Cloud Architect] 12. Defensive Security in the Cloud
    [SAP] 38. Database Migration Service
    [Cloud Architect] 11. Protecting Data Stored in the Cloud
    [SAP] 37. Snow family
    [SAP] 36. Storage getway
    JAVA开发常见问题整理(持续更新)
    sdf1434 最少转弯
    sdf 2439 问题 A: 迷宫(广搜模板题)
    sdf1552
    小学生数据结构和基础算法
  • 原文地址:https://www.cnblogs.com/wghao/p/1203623.html
Copyright © 2020-2023  润新知