代码之家  ›  专栏  ›  技术社区  ›  Karl

SQL Server 2008使用ISNULL语句优化完全联接

  •  2
  • Karl  · 技术社区  · 15 年前

    大家好

    我有这个表(简化示例):

        CREATE TABLE [dbo].[dataTable]
        (
        [ID] [int] IDENTITY(1,1) NOT NULL,
        [dteEffectiveDate] [date] NULL,
        [dtePrevious] [date] NULL,
        [dteNext] [date] NULL,
        [Age] [int] NULL,
        [Count] [int] NULL
        ) ON [PRIMARY]
    
        GO
    

    以下是一些输入值:

    INSERT INTO [YourDB].[dbo].[dataTable]
               ([dteEffectiveDate]
               ,[dtePrevious]
               ,[dteNext]
               ,[Age]
               ,[Count])
         VALUES
    ('2009-01-01',NULL,'2010-01-01',40,300),
    ('2010-01-01','2009-01-01', NULL,40,200),
    ('2009-01-01',NULL, '2010-01-01',20,100),
    ('2010-01-01','2009-01-01', NULL,20,50),
    ('2009-01-01',NULL,'2010-01-01',30,10)
    GO
    

    每个条目都有一个DTeeEffectiveDate字段。此外,每一个都有一个dteperious和dteNext,反映最近的上一个/下一个生效日期的日期。现在我需要的是一个查询,它将计算特定年龄段内连续期间计数字段的中间值。

    注意,30岁只有一个条目,10。这是2009年1月1日。在2010/01/01没有条目,但是我们知道数据是在这一点上捕获的,所以事实上没有任何东西意味着30在这一天是0。因此查询应该产生5。

    为了实现这一点,我在表本身上使用了一个完全联接,并使用ISNULL来选择值。这是我的密码:

    SELECT
    
        ISNULL(T1.dteEffectiveDate,T2.dtePrevious) as [Start Date]
        ,ISNULL(T1.dteNext,T2.dteEffectiveDate)  as [End Date]
        ,ISNULL(T1.Age,T2.Age) as Age 
        ,ISNULL(T1.[Count],0) as [Count Start]
        ,ISNULL(T2.[Count],0)   as [Count End]
        ,(ISNULL(T1.[Count],0)+ISNULL(T2.[Count],0))/2 as [Mid Count]
    
        FROM
        [ExpDBClient].[dbo].[dataTable] as T1
        FULL JOIN [ExpDBClient].[dbo].[dataTable] as T2
    
        ON 
        T2.dteEffectiveDate = T1.dteNext
        AND T2.Age = T1.Age
    
        WHERE ISNULL(T1.dteEffectiveDate,T2.dtePrevious) is not null
        AND ISNULL(T1.dteNext,T2.dteEffectiveDate) is not null
    
    GO
    

    Start Date  End Date    Age Count Start Count End   Mid Lives
    2009-01-01  2010-01-01  40  300         200         250
    2009-01-01  2010-01-01  20  100         50          75
    2009-01-01  2010-01-01  30  10          0           5
    

    它工作得很好,但当我在实际数据(约700万条记录)上运行它时,执行起来要花很长时间。

    有人有什么建议吗?


    卡尔

    1 回复  |  直到 15 年前
        1
  •  2
  •   marc_s MisterSmith    15 年前

    很难提出很多建议。

    • Age
    • dteEffectiveDate
    • dteNext

    分别在每一列上创建一个非聚集索引,然后再次测量。只有几个数据行,没有可以衡量的改进—但是有数百万行,这可能会有所不同。