使用Group By时,每天不同的最大值和最小值

时间:2017-10-19 10:04:13

标签: sql sql-server group-by dynamic-sql

我遇到了一个奇怪的问题。 我有两个存储过程,非常相似。 一个计算整个月的总KWh使用量,

SET     @SQL =
N'SELECT '''+ RIGHT(convert(varchar(11), DATEADD(m,0, @Date),106),8)+''' AS Reporting_Period,
    MAX(A) - MIN(A) AS KWh
    FROM MyTable
    WHERE [timestamp] BETWEEN '''+ @FirstDay +'''AND '''+ @EndThisMonth +''' '

另一个计算相同但每天,如下所示

SELECT CAST(timestamp as DATE) AS Day,
    MAX(A) - MIN(A) AS KWh
    FROM MyTable
    WHERE [timestamp] BETWEEN '''+ @FirstDay +'''AND '''+ @EndThisMonth +''' 
    GROUP BY CAST(timestamp as DATE) 

     '

但是当我每天将Kwh列汇总在一起时,该值与第一个查询略有不同。

两个查询变量都是相同的

DECLARE 
        @SQL            NVARCHAR(MAX),
        @EndThisMonth   NVARCHAR(20),
        @FirstDay       NVARCHAR(20)
SET     @EndThisMonth = CONVERT(VARCHAR(20), DATEADD(DAY,1,EOMONTH (@Date)),126)

SET     @FirstDay     = CONVERT(varchar(20),DATEADD(DAY,1, EOMONTH (@Date,-1)),126)  

任何想法? 注意:我简化了查询,但它必须是动态SQL,它只有一列A

这是样本数据:

timestamp                     A
----------                 -------
2017-10-19 01:00:00          135.5
2017-10-19 02:00:00          146.5
2017-10-19 03:00:00          157.2
2017-10-19 04:00:00          169.1
2017-10-19 05:00:00          176.8
 .....
 .....
 .....
2017-10-20 04:00:00          334.5
2017-10-20 05:00:00          349.7
2017-10-20 06:00:00          358.5
 .....
 .....
 .....

1 个答案:

答案 0 :(得分:0)

我发现我的问题在哪里。

如果你看看这张表:

    timestamp                     A
    ----------                 -------
    2017-10-19 01:00:00          135.5
    2017-10-19 02:00:00          146.5
    2017-10-19 03:00:00          157.2
    .....
    .....
    2017-10-20 04:00:00          199.1
    2017-10-20 05:00:00          216

我对该月的第一次查询获得该月的max(A) - min(A),即 216 - 135.5 = 80.5这是正确的。

但是当我每天对它们进行分组时,我得到每个特定日期的Max(A)-Min(A),每天的delta应选择为第2天的Max(A) - Max(A)第1天。

见下文

for Day 19/10
157.2-135.5=21.7

for day 20/10
216.8-199.1=17.7

Now the total is 
21.7+17.7=39.4  which is wrong.

然后计算每天的总使用量,我需要获得最大的一天 - 前一天的最大值,然后将它们分组并在下面我通过使用cte实现它

;WITH cte AS
(
   SELECT 
      ROW_NUMBER() OVER(ORDER BY DATEADD(DAY, DATEDIFF(DAY, 0, timestamp), 0) ) AS ROW,
      DATEADD(DAY, DATEDIFF(DAY, 0, timestamp), 0) AS DateVal,
      MAX(A) AS max_eTotal
  FROM 
      myTable
  GROUP BY
      DATEADD(DAY, DATEDIFF(DAY, 0, timestamp), 0)
)
SELECT c2.DateVal, c2.max_eTotal - c1.max_eTotal
FROM cte c1 
INNER JOIN cte c2 ON c1.row = c2.row-1
WHERE c2.DateVal BETWEEN @FirstDay AND @EndThisMonth 

但感谢大家的帮助