【问题标题】:SQL query - sum of values by status for date intervalSQL查询 - 日期间隔状态的值总和
【发布时间】:2014-06-01 16:57:31
【问题描述】:

我因为一个查询而发疯。我有一个如下表,我想获取一个数据 - 间隔中每个日期的状态值总和。

表格

Id    Name    Value    Date        Status
1     pro1    2        01.04.14    0 
2     pro1    8        02.04.14    1 
3     pro2    6        02.04.14    1
4     pro3    0        03.04.14    0
5     pro4    7        03.04.14    0
6     pro4    2        03.04.14    0
7     pro4    4        03.04.14    1
8     pro4    6        04.04.14    1
9     pro4    1        04.04.14    1

例如,

输入: 姓名 = pro4,minDate = 01.02.14,maxDate = 04.09.14

输出:

Date           Values sum for 0 Status          Values sum for 1 Status    
01.04.14       0                                0
02.04.14       0                                0
03.04.14       9   (=7+2)                       4  (only 4 exist)
04.04.14       0                                7  (6+1)

01.02.1402.04.14 日期中,pro4 没有按状态显示的值,但我想显示这些行,因为我需要该间隔内的所有日期。谁能帮我创建这个查询?

编辑:

我不能改变结构,我已经有了那个有数据的表。每天在表中存在多次(最少 1 次)

提前致谢。

【问题讨论】:

  • 您是否有某种日历表,每个日期都有一行?
  • 查看this 了解如何使用 SQLServer 创建日历
  • 不,我没有。我想在日期间隔中获得 1 天 1 时间
  • 请参阅我有问题的编辑部分

标签: sql sql-server tsql group-by sql-order-by


【解决方案1】:

假设表格中的每个日期都有一行,请使用条件聚合:

select date,
       sum(Case when name = 'pro4' and status = 0 then Value else 0 end) as values_0,
       sum(case when name = 'pro4' and status = 1 then Value else 0 end) as values_1
from Table t
where date >= '2014-04-01' and date <= '2014-04-09'
group by date
order by date;

如果您没有此日期列表,则可以采用此方法:

with dates as (
      select cast('2014-04-01' as date) as thedate
      union all
      select dateadd(day, 1, thedate)
      from dates
      where thedate < '2014-04-09'
)
select dates.thedate,
       sum(Case when status = 0 then Value else 0 end) as values_0,
       sum(case when status = 1 then Value else 0 end) as values_1
from dates left outer join
     table t
     on t.date = dates.thedate and t.name = 'pro4'
group by dates.thedate;

【讨论】:

  • Gordon,它给出了“')' 附近的语法错误”这里:然后值 0)
  • @JhoonBey 。 . .根据您的修改,第一个版本应该可以工作。
【解决方案2】:

只是一个假设查询:

select Distinct date ,case when status = 0 and MAX(date) then SUM(value) ELSE 0 END Status0 ,
case when status = 1 and MAX(date) then SUM(value) ELSE 0 END Status1  from table 

【讨论】:

    【解决方案3】:

    为了扩展我的评论,完整的查询是

    WITH [counter](N) AS
    (SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
     SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
     SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
     SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
     SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
     SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
     SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
     SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
     SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
     SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
     SELECT 1)
    , days(N) AS (
      SELECT row_number() over (ORDER BY (SELECT NULL)) FROM [counter])
    , months (N) AS (
      SELECT N - 1 FROM days WHERE N < 13)
    , calendar ([date]) AS (
      SELECT DISTINCT cast(dateadd(DAY, days.n
                         , dateadd(MONTH, months.n, '20131231')) AS date)
      FROM months
           CROSS JOIN days
      )
    SELECT a.Name
         , c.Date
         , [Sum of 0] = SUM(CASE Status WHEN 0 THEN Value ELSE 0 END)
         , [Sum of 1] = SUM(CASE Status WHEN 1 THEN Value ELSE 0 END)
    FROM   Calendar c
           LEFT  JOIN myTable a ON c.Date = a.Date AND a.name = 'pro4'
    WHERE  c.date BETWEEN '20140201' AND '20140904'
    GROUP BY c.Date, a.Name
    ORDER BY c.Date
    

    请注意,名称的条件需要在 JOIN 中,否则您将只能获得表格的日期。
    如果您需要多年,只需在 CTE 日历中添加另一个 CTE 计数和 dateadd(YEAR,...)

    【讨论】:

      【解决方案4】:

      这并不是真正的确切查询,但我认为您可以通过如下查询来获得:

      select date, status, sum(value) from table
          where (date between mindate and maxdate) and name = product_name
          group by date, status;
      

      page 提供更多信息。

      编辑

      所以上面的查询只给出了 OP 要求的部分答案。原始表的LEFT OUTER JOIN 和上面对datestatus 字段的查询结果将给出缺失的信息。

      例如

      select x.date, x.status, x.sum_of_values from table as y 
      left outer join 
      (select date, status, sum(value) as sum_of_values 
          from table 
          where (date between mindate and maxdate) and name = product_name 
          group by date, status) as x 
      on y.date= x.date and y.status = x.status
      order by x.date;
      

      【讨论】:

        猜你喜欢
        • 2011-09-02
        • 1970-01-01
        • 1970-01-01
        • 2017-05-25
        • 2018-10-09
        • 2018-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多