SQL查询-日期间隔的状态值总和

SQL查询-日期间隔的状态值总和,sql,sql-server,tsql,group-by,sql-order-by,Sql,Sql Server,Tsql,Group By,Sql Order By,我因为一个问题而发疯。我有一个如下的表,我想得到一个数据汇总值的状态为每个日期的间隔 桌子 比如说, 输入:Name=pro4,minDate=01.02.14,maxDate=04.09.14 输出: 在01.02.14和02.04.14日期中,pro4没有按状态显示的值,但我想显示该行,因为我需要该时间间隔内的所有日期。有人能帮我创建这个查询吗 编辑: 我不能改变结构,我已经有了那个表的数据。每天至少1次多次出现在表中 提前感谢。只是一个假设查询: select Distinct date

我因为一个问题而发疯。我有一个如下的表,我想得到一个数据汇总值的状态为每个日期的间隔

桌子

比如说,

输入:Name=pro4,minDate=01.02.14,maxDate=04.09.14

输出:

在01.02.14和02.04.14日期中,pro4没有按状态显示的值,但我想显示该行,因为我需要该时间间隔内的所有日期。有人能帮我创建这个查询吗

编辑:

我不能改变结构,我已经有了那个表的数据。每天至少1次多次出现在表中


提前感谢。

只是一个假设查询:

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 

这并不是一个精确的查询,但我认为您可以通过一个如下所示的查询来实现:

select date, status, sum(value) from table
    where (date between mindate and maxdate) and name = product_name
    group by date, status;
这提供了更多信息

编辑

因此,上面的查询只给出了OP所需答案的一部分。原始表的左外部联接以及上面对Date和status字段的查询结果将给出缺少的信息

e、 g


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

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;

要展开我的注释,完整的查询是

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
请注意,名称上的条件必须在联接中,否则只能得到表的日期。
如果您需要多年,只需为计数添加另一个CTE和dateaddYEAR,。。。在CTE日历中

是否有某种日历表,其中每个日期都有一行?检查如何使用SQLServerNo创建日历我没有。我想得到一个1天1次的日期间隔参见我的编辑部分中的问题plzGordon,它在附近给出了错误的语法:then Value else0@JhoonBey . . . 根据您的编辑,第一个版本应该可以工作。
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;
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