[英]SQL query - sum of values by status for date interval
I get crazy because of one query. 我因为一个查询而发疯。 I have a table like following and I want to get a data - Summa of Values by Status For every Date in interval. 我有一个类似以下的表格,我想获取一个数据- 状态中每个日期的值总和。
Table 表
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
For example, 例如,
Input: Name = pro4, minDate = 01.02.14, maxDate = 04.09.14 输入: 名称= pro4,minDate = 01.02.14,maxDate = 04.09.14
Output: 输出:
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)
In 01.02.14
and 02.04.14
dates, pro4
has not values by status, but I want to show that rows, because I need all dates in that interval. 在01.02.14
和02.04.14
. 01.02.14
02.04.14
日期中, pro4
没有按状态显示的值,但是我想显示该行,因为我需要该间隔中的所有日期。 Can anyone help me to create this query? 谁能帮助我创建此查询?
Edit: 编辑:
I can not change structure, I have already that table with data. 我无法更改结构,我已经有了带有数据的表。 Every day exist in table many times (minimum 1 time) 每天在表中存在多次(最少1次)
Thanks in advance. 提前致谢。
Assuming you have a row for each date in the table, use conditional aggregation: 假设表中的每个日期都有一行,请使用条件聚合:
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;
If you don't have this list of dates, you can take this approach instead: 如果没有此日期列表,则可以采用以下方法:
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;
just an assumption query : 只是一个假设查询:
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
This is not really the exact query, but I think you can get that by having a query that looks like: 这实际上不是确切的查询,但是我认为您可以通过以下查询来实现:
select date, status, sum(value) from table
where (date between mindate and maxdate) and name = product_name
group by date, status;
this page gives more info. 此页面提供更多信息。
EDIT 编辑
So the above query only gives a part of the answer required by the OP. 因此,以上查询仅给出了OP所需答案的一部分。 A LEFT OUTER JOIN
of the original table and the result of the above query on the date
and status
fields will give the missing info. 原始表的LEFT OUTER JOIN
以及date
和status
字段的上述查询结果将提供缺少的信息。
eg 例如
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;
To expand my comment the complete query is 为了扩大我的评论,完整的查询是
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
Note that the condition on the name need to be in the JOIN, otherwise you'll get only the date of your table. 请注意,名称上的条件必须在JOIN中,否则您将仅获得表格的日期。
If you need multiple years just add another CTE for the count and a dateadd(YEAR,...) in the CTE calendar 如果您需要多年,只需在CTE日历中添加另一个CTE作为计数和dateadd(YEAR,...)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.