Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL查询正在运行的日期值聚合-365天,其中涉及SUM和GROUP BY子句_Sql_Reporting Services_Sql Server 2012_Aggregate Functions - Fatal编程技术网

SQL查询正在运行的日期值聚合-365天,其中涉及SUM和GROUP BY子句

SQL查询正在运行的日期值聚合-365天,其中涉及SUM和GROUP BY子句,sql,reporting-services,sql-server-2012,aggregate-functions,Sql,Reporting Services,Sql Server 2012,Aggregate Functions,设置:SQL Server 2012,使用报表生成器3.0在SSRS中的折线图中使用数据 我有一个销售数据表,第一笔交易发生在2012年10月10日。此表用于定期更新销售信息,并将在将来继续写入(当前日期为11/26/13,这就是示例表停在此处的原因) 以下是我开始使用的原始数据示例: StartDate Product PaidQty UnPaidQty --------------------------------------------

设置:SQL Server 2012,使用报表生成器3.0在SSRS中的折线图中使用数据

我有一个销售数据表,第一笔交易发生在2012年10月10日。此表用于定期更新销售信息,并将在将来继续写入(当前日期为11/26/13,这就是示例表停在此处的原因)

以下是我开始使用的原始数据示例:

StartDate          Product         PaidQty          UnPaidQty
-------------------------------------------------------------
2012-10-10         Product A       100              150
2012-10-10         Product B       110              50
2012-10-10         Product C       10               100
2012-10-11         Product A       120              200
2012-10-11         Product D       140              230
2012-10-11         Product E       180              20
...
2013-05-01         Product H       120              60
2013-05-01         Product J       90               90
2013-05-01         Product K       120              160
...
2013-11-25         Product B       90               80
2013-11-25         Product F       190              180
2013-11-25         Product G       120              60
注意:并非每个日期都有值。例如,12/25/12没有一行

我想以这样的方式结束:

StartDate          DailyTotal      AnnualTotal
--------------------------------------------
2012-10-10         520             520       <-- The Sum of 10/10/12 through 10/10/12
2012-10-11         890             1410      <-- The Sum of 10/10/12 through 10/11/12
...
2013-05-01         640             278,000   <-- The Sum of 10/10/12 through 05/01/13
...
2013-11-25         720             450,500   <-- The Sum of 11/26/12 through 11/25/13
但是,我需要得到的数据能够提供我每天的总收入(支付+未支付)以及前365天的运行总收入。因此,由于2012年10月10日之前不存在任何数据,运行总计将对2012年10月10日至2013年10月11日期间的总计进行汇总,此时将对
起始日期
值的总计进行汇总-365天。有一个很大的产品清单,任何一种都可以在任何一天出售,但对于我的最终结果,我不在乎产品。此信息通过使用
GROUP BY
子句为每个日期返回一行而发挥作用

我只是没有掌握我需要做什么,以便为一个连续的年度总数添加一个额外的列。我尝试使用
OVER()
子句,例如:

SELECT StartDate, SUM(PaidQty) + SUM(UnPaidQty) AS Total, SUM(PaidQty) + SUM(UnPaidQty) OVER (ORDER BY StartDate) AS AnnualTotal
FROM Table
GROUP BY StartDate
ORDER BY StartDate 
但这会错误地提示PaidQty和UnPaidQty需要位于聚合函数或
GROUP BY
子句中。如果我将这些添加到
GROUPBY
子句中,那么每个日期都会有多行,并且运行值不正确

编辑:正如下面Aaron的回答所暗示的,我最终提出了以下问题:

    IF OBJECT_ID('tempdb..#x') IS NOT NULL DROP TABLE #x 
CREATE TABLE #x
(
    StartDate   DATETIME,
    PaidQty     INT,
    UnPaidQty   INT
)
INSERT INTO #x
SELECT StartDate, SUM(PaidQty), SUM(UnPaidQty)
FROM MyTable
GROUP BY StartDate

SELECT Date, PaidQty+UnPaidQty AS DailyTotal, 
            SUM(PaidQty+UnPaidQty) OVER (Order By Date ROWS 364 PRECEDING) AS AnnualTotal
FROM CalendarDates
LEFT JOIN #x ON Date = StartDate
WHERE Date BETWEEN '2012-10-10' AND GetDate()
ORDER BY Date
我在数据库中创建了一个名为CalendarDates的表,其中只包含从2010年1月1日到2100年12月31日的所有日期的列表。这用于为未完成销售的任何日期填写NULL

DECLARE @x TABLE(StartDate DATE, Product VARCHAR(30), PaidQty INT, UnPaidQty INT);

INSERT @x VALUES
('2012-10-10','Product A',100,150),
('2012-10-10','Product B',110,50 ),
('2012-10-10','Product C',10 ,100),
('2012-10-11','Product A',120,200),
('2012-10-11','Product D',140,230),
('2012-10-11','Product E',180,20 ),
('2012-10-12','Product B',90 ,80 ),
('2012-10-12','Product F',190,180),
('2012-10-12','Product G',120,60 );

;WITH x AS
(
  SELECT StartDate, pq = SUM(PaidQty), uq = SUM(UnPaidQty)
  FROM @x GROUP BY StartDate
)
SELECT StartDate, pq, uq,
  SUM(pq+uq) OVER (ORDER BY StartDate ROWS 365 PRECEDING)
FROM x;
现在,假设每个日期都有一行。如果没有,您可能希望生成一组日期,并将其用作左连接中的锚定。否则,前面的365行将表示365天以上。为此:

DECLARE @minDate DATE, @maxDate DATE, @delta INT;

SELECT @maxDate = MAX(StartDate), @minDate = MIN(StartDate) FROM @x;

SET @delta = DATEDIFF(DAY, @minDate, @maxDate);

IF @delta > 364
  SELECT @minDate = DATEADD(DAY, -364, @maxDate), @delta = 364;

;WITH n(n) AS
(
  SELECT TOP (@delta+1) ROW_NUMBER() OVER (ORDER BY [object_id])
  FROM sys.all_columns
),
d(d) AS (SELECT DATEADD(DAY, n-1, @minDate) FROM n),
x AS 
(
  SELECT StartDate = d.d, pq = SUM(PaidQty), uq = SUM(UnPaidQty)
    FROM d LEFT OUTER JOIN @x AS x 
    ON d.d = x.StartDate GROUP BY d.d
)
SELECT StartDate, pq, uq,
  SUM(pq+uq) OVER (ORDER BY StartDate ROWS 365 PRECEDING)
FROM x
ORDER BY StartDate;

所以你关心的是每天的总数,而不是每种产品的总数?正确。我只想知道每天的产品总数。我不想按产品细分。所以您想包含开始日期之前的数据?那么开始日期的意义是什么呢?使用参数,包括开始日期,是简化您提供的查询的一种方法。我承认
@Begin
之前的数据将被排除在外,这不是我想要的。“…由
@Begin
定义的初始日期实际上不需要发挥作用。我可以使用SSRS将结果过滤到更明确的日期范围”这很有效,但假设每个日期都有一行。一年中会有一些没有任何数据的日期,我不一定能够在没有销售的每一天都继续添加日期。我还修改了最后的
SELECT
语句,因为我需要总计,未付总计与未付总计。因此,我在(前面365行的起始日期顺序)上使用了这个
SUM(pq+uq)
。小细节,但我想清楚我需要完成什么。@BobbyScon我在回答中提到了缺失的日期——我不认为做出这样的假设是我的错;如果缺少天数,则应将其作为问题陈述的一部分。无意采取任何态度/冒犯。我甚至投票支持你的答案,因为它是正确的,但我没有接受它作为最终答案,因为它不是我所需要的。我最初的问题是查找前365天,而不是前365天的值。“对不起,我说得不清楚。”“是的,如果你错过了日期,你应该说清楚。例如,您的示例数据可能遗漏了日期。如果您提供连续的示例数据,那么逻辑假设是所有数据都是连续的。我最初的问题和示例数据是在以下前提下提供的:答案将包含某种形式的
OVER()
语句,该语句包含基于日历日期的约束,而不是计算行数。我喜欢你的方法,决不辜负你的观点,但直到我看到你做了什么来解决这个问题,我才不认为错过的日期会起作用。你提出的解决方案远比我最初预期的复杂——答案是,所以我非常感谢你提供的完整回复。
DECLARE @minDate DATE, @maxDate DATE, @delta INT;

SELECT @maxDate = MAX(StartDate), @minDate = MIN(StartDate) FROM @x;

SET @delta = DATEDIFF(DAY, @minDate, @maxDate);

IF @delta > 364
  SELECT @minDate = DATEADD(DAY, -364, @maxDate), @delta = 364;

;WITH n(n) AS
(
  SELECT TOP (@delta+1) ROW_NUMBER() OVER (ORDER BY [object_id])
  FROM sys.all_columns
),
d(d) AS (SELECT DATEADD(DAY, n-1, @minDate) FROM n),
x AS 
(
  SELECT StartDate = d.d, pq = SUM(PaidQty), uq = SUM(UnPaidQty)
    FROM d LEFT OUTER JOIN @x AS x 
    ON d.d = x.StartDate GROUP BY d.d
)
SELECT StartDate, pq, uq,
  SUM(pq+uq) OVER (ORDER BY StartDate ROWS 365 PRECEDING)
FROM x
ORDER BY StartDate;