【问题标题】:SQL Server partitioning monthly data by weeks and calculating weekly weighted average based on month days of that week belong toSQL Server 按周对月度数据进行分区,并根据该周的月天数计算周加权平均值属于
【发布时间】:2012-10-19 00:56:18
【问题描述】:

我有一张这样的桌子:

Month          Value
2012-08-01      0.345
2012-09-01      0.543
2012-10-01      0.321
2012-11-01      0.234
2012-12-01      0.234

用户输入的星期范围从“2012-09-29”到“2012-10-13” 输出应显示请求范围内所有周的结果以及每周的平均值,逻辑如下: - 如果所有工作日都在一个月内,只需使用该月的月值 - 如果工作日分布在两个月内,则将每周值计算为这两个月之间的平均值,优先考虑包含该周中天数最多的月份。

如果有人能告诉我如何在 T-SQL 中做这样的事情,将不胜感激。

【问题讨论】:

    标签: sql-server tsql


    【解决方案1】:

    last query 就是一个例子。 Calendar 表是根据请求构建的,但每个数据库都可以使用持久的 Calendar 表,您可以在该表上过滤日期范围。

    declare @tbl table (
      Month datetime,
      Value decimal(10,3));
    insert @tbl select
    '2012-08-01',      0.345 union all select
    '2012-09-01',      0.543 union all select
    '2012-10-01',      0.321 union all select
    '2012-11-01',      0.234 union all select
    '2012-12-01',      0.234;
    
    declare @start datetime, @end datetime;
    select @start = '2012-09-29', @end ='2012-10-13';
    
    ;with Calendar(TheDate,StartOfWeek,StartOfMonth) as(
      select @start, @start+1-Datepart(dw,@start), @start-Day(@start)+1
      union all
      select TheDate+1, TheDate+1+1-Datepart(dw,TheDate+1),
             TheDate+1-Day(TheDate+1)+1
      from Calendar
      where TheDate < @end
    )
    select case when @start > v.StartOfWeek
                then @start else v.StartOfWeek end RangeStart,
           case when @end < v.StartOfWeek+6
                then @end else v.StartOfWeek+6 end RangeEnd,
           cast(avg(m.value) as decimal(10,3)) [Average]
    from Calendar v
    join @tbl m on v.StartOfMonth = m.Month
    group by v.StartOfWeek;
    

    输出

    RANGESTART          RANGEEND            Average
    September, 29 2012  September, 29 2012  0.543
    September, 30 2012  October, 06 2012    0.353
    October, 07 2012    October, 13 2012    0.321
    

    【讨论】:

      【解决方案2】:

      您的查询将是这样的。思路是求下个月的第一天DATEADD(mm, DATEDIFF(mm, 0, Month) + 1, 0。计算天数,就可以得到每月的总数,并根据当月第一天与下个月的差值计算平均值。(SQL语法可能需要一些清理)。

      declare @startdate datetime
      declare  @enddate datetime
      
      set @startdate = '2012-09-05'
      set @enddate ='2012-10-13'
      
       Select Monthtotal/DateDiff(d,Month,NextMonth)
          FROM
              (Select 
               Month, DATEADD(mm, DATEDIFF(mm, 0, Month) + 1, 0) NextMonth, 
               DateDiff(d,Month, DATEADD(mm, DATEDIFF(mm, 0, Month) + 1, 0) * Value as Monthtotal
              FROM  DatesTable
              WHERE 
                  @startdate >= Month and 
                  @enddate <= DATEADD(mm, DATEDIFF(mm, 0, Month) + 1, 0)) 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-07
        • 1970-01-01
        相关资源
        最近更新 更多