【问题标题】:Changes to a Query Based on Year基于年份的查询更改
【发布时间】:2010-10-26 22:23:13
【问题描述】:
    select datepart(month,s1.Timeperiod) as monthofaum, 
           datepart(YEAR,s1.Timeperiod) as Yearofaum,
           ISNULL(s2.endingAum,0) as Starting_Aum, 
           s1.endingAum as Ending_Aum
    from #temp_1 s1
    left outer join (select * from #temp_1)s2
    on month(s1.Timeperiod) = dateadd(D,1,month(s2.Timeperiod))

这非常适合按月计算,但假设我需要更改查询以获取基于年份的结果 - 我应该在哪里进行更改?

Example
    monthofaum  Yearofaum   Starting_Aum          Ending_Aum
    ----------- ----------- --------------------- ---------------------
    11          2009        0.00                  0.00
    12          2009        0.00                  1059594254.86
    1           2010        0.00                  1083195051.98
    2           2010        1083195051.98         1125314638.64
    3           2010        1125314638.64         1212355911.70
    4           2010        1212355911.70         1270374634.62
    5           2010        1270374634.62         1265193377.27
    6           2010        1265193377.27         1260776179.02
    7           2010        1260776179.02         2599205697.44
    8           2010        2599205697.44         1323838670.57

如果您查看数据可以看到,对于 2010 年,上个月的 Ending Aum 值将等于下个月的 Starting Aum,但对于 2009 年,dec Ending Aum 未分配给 2010 年 1 月的期初 Aum .

这是我需要修复的错误。

【问题讨论】:

    标签: sql sql-server sql-server-2005 tsql


    【解决方案1】:

    要调整年份,只需比较月份和年份。例如,

    select convert(varchar(7), getdate(), 120)
    

    打印2010-10。应用于您的查询,您可以重写on,例如:

    on convert(varchar(7), s1.TimePeriod, 120) = 
       convert(varchar(7), DateAdd(year, 1, s2.TimePeriod), 120)
    

    附:子查询不是必需的。这一行:

     left outer join (select * from #temp_1)s2
    

    完全一样:

     left outer join  #temp_1 s2
    

    【讨论】:

    • (select * from #temp_1) 的子查询也困扰着我。
    【解决方案2】:

    这是假设你不关心我认为这会起作用的时间......

    select datepart(month,s1.Timeperiod) as monthofaum,  
       datepart(YEAR,s1.Timeperiod) as Yearofaum, 
       ISNULL(s2.endingAum,0) as Starting_Aum,  
       s1.endingAum as Ending_Aum 
    from #temp_1 s1 
    left outer join (select * from #temp_1) s2 
    on s1.TimePeriod = DateAdd(year,1,s2.TimePeriod)
    



    编辑:
    或者,如果您确实关心时间,您可以试试这个(为了方便起见,我有一个功能)......

    1.创建dateonly函数

    CREATE FUNCTION [dbo].[fn_DateOnly](@DateTime DATETIME)
    -- Returns @DateTime at midnight; i.e., it removes the time portion of a DateTime value.
    RETURNS  DATETIME
    AS
    BEGIN
    RETURN DATEADD(dd,0, DATEDIFF(dd,0,@DateTime))
    END
    

    2。这使您可以:

    select datepart(month,s1.Timeperiod) as monthofaum,  
       datepart(YEAR,s1.Timeperiod) as Yearofaum, 
       ISNULL(s2.endingAum,0) as Starting_Aum,  
       s1.endingAum as Ending_Aum 
    from #temp_1 s1 
    left outer join (select * from #temp_1) s2 
    on dbo.fn_DateOnly(s1.TimePeriod) = DateAdd(year,1,dbo.fn_DateOnly(s2.TimePeriod))
    

    【讨论】:

    • 如果 TimePeriod 仅包含该月第一天午夜的日期,这将起作用
    • @Adomar - 是的,没错,但我试图通过添加“这是假设你不关心时间”来限定它。但我确实更新了我的答案以说明时间。
    • @AGoodDisplayName:这适用于比较天数,但问题是比较月份。所以你需要一个fn_MonthOnly :)
    • @Adomar - 你的权利。 @Sravs - 现在无法修复,得走了......祝你好运
    • 我想根据月份和年份进行查询
    【解决方案3】:
    select 
        datepart(month,s1.Timeperiod) as monthofaum, 
        datepart(YEAR,s1.Timeperiod) as Yearofaum,
        ISNULL(s2.endingAum,0) as Starting_Aum,  
        s1.endingAum as Ending_Aum 
    from 
        #temp_1 s1 
    left outer join 
        (select * from #temp_1) s2 on (month(s1.Timeperiod)-1 = month(s2.Timeperiod) 
                                   or (month(s1.Timeperiod) = 1 and month(s2.Timeperiod) = 12))
    

    如果表仅包含 2 年的数据,则上述查询有效。如果我找出上述查询的问题,我会及时通知大家

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多