SQL 对过去三周的周日到周六之间的值求和



我正在处理一个 T-SQL 查询,以获取过去三周从星期日到星期六的读数和本周的预测值的总和。目标是比较每周的值以显示趋势。

本周的预测计算是上周日的读数总和*(7/一周的一天(

示例:(27 * (7/4(,因为今天星期三是一周的第4天。

示例数据如下

+----+---------+-------------+
| ID | Reading | ReadingDate |
+----+---------+-------------+
|  1 |       0 | 9/19/2018   |
|  1 |      27 | 9/18/2018   |
|  1 |       0 | 9/17/2018   |
|  1 |       0 | 9/16/2018   |
|  1 |       0 | 9/15/2018   |
|  1 |       0 | 9/14/2018   |
|  1 |       7 | 9/13/2018   |
|  1 |      12 | 9/12/2018   |
|  1 |       0 | 9/11/2018   |
|  1 |       0 | 9/10/2018   |
|  1 |      17 | 9/9/2018    |
|  1 |      22 | 9/8/2018    |
|  1 |       0 | 9/7/2018    |
|  1 |       0 | 9/6/2018    |
|  1 |       0 | 9/5/2018    |
|  1 |      24 | 9/4/2018    |
|  1 |       0 | 9/3/2018    |
|  1 |       0 | 9/2/2018    |
|  1 |      17 | 9/1/2018    |
|  1 |       0 | 8/31/2018   |
|  1 |      19 | 8/30/2018   |
|  1 |       0 | 8/29/2018   |
|  1 |       0 | 8/28/2018   |
|  1 |       0 | 8/27/2018   |
|  1 |       0 | 8/26/2018   |
+----+---------+-------------+

我希望结果如下。

+----+---------+------+------+------+-----------+-----------+-----------+
| ID | Current | Wk_1 | Wk_2 | wk_3 | Wk1_Trend | Wk2_Trend | Wk3_Trend |
+----+---------+------+------+------+-----------+-----------+-----------+
|  1 |      63 |   36 |   46 |   36 | Up        | Down      | Up        |
+----+---------+------+------+------+-----------+-----------+-----------+

但我得到了以下内容。

+----+--------------+-------------+-------------+-------------+-----------+-----------+-----------+-----------------+------------------+-----------------+
| ID | Reading_crnt | Reading_wk1 | Reading_wk2 | Reading_wk3 | Wk1_Trend | Wk2_Trend | Wk3_Trend | Record_Date_wk1 | Record_Date2_wk2 | Record_Date_wk3 |
+----+--------------+-------------+-------------+-------------+-----------+-----------+-----------+-----------------+------------------+-----------------+
|  1 |        47.25 |          27 |         118 |           0 | Up        | Down      | Up        | 9/16/2018       | 8/29/2018        | 8/8/2018        |
+----+--------------+-------------+-------------+-------------+-----------+-----------+-----------+-----------------+------------------+-----------------+

这是创建的脚本,但我看到日期范围不同。请帮我解决这个问题。

WITH 
TRTx AS (SELECT (SUM(t1.Reading) * (cast(7 as float)/cast(DATEPART(WEEKDAY,GETDATE()) as float))) Reading_wkexp, t1.ID, CAST(DATEADD(DAY, -1 * ((DATEPART(WEEKDAY, GETDATE()) % 7) - 1), GETDATE()) AS DATE) AS Record_Date
FROM Trend_T t1
WHERE t1.Record_Date BETWEEN CAST(DATEADD(DAY, -1 * ((DATEPART(WEEKDAY, GETDATE()) % 7) - 1), GETDATE()) AS DATE) AND (SELECT max(Record_Date) FROM Trend_T) GROUP BY t1.ID
),
TRT1 AS (SELECT SUM(t1.Reading) Reading_wk1, t1.ID, CAST(DATEADD(DAY, -1 * ((DATEPART(WEEKDAY, GETDATE()) % 7) - 1), GETDATE()) AS DATE) AS Record_Date
FROM Trend_T t1
WHERE t1.Record_Date BETWEEN CAST(DATEADD(DAY, -1 * ((DATEPART(WEEKDAY, GETDATE()) % 7) - 1), GETDATE()) AS DATE) AND (SELECT max(Record_Date) FROM Trend_T) GROUP BY t1.ID
),
TRT2 AS (SELECT SUM(t2.Reading) Reading_wk2, t2.ID, CAST(DATEADD(DAY, -6 * ((DATEPART(WEEKDAY, GETDATE()) % 7) - 1), TRT1.Record_Date) AS DATE) AS Record_Date2
FROM Trend_T t2 
JOIN TRT1 ON TRT1.ID = t2.ID
WHERE t2.Record_Date BETWEEN CAST(DATEADD(DAY, -6 * ((DATEPART(WEEKDAY, GETDATE()) % 7) - 1), TRT1.Record_Date) AS DATE) AND TRT1.Record_Date
GROUP BY t2.ID, TRT1.Record_Date 
),
TRT3 AS (SELECT SUM(t3.Reading) Reading_wk3, t3.ID, CAST(DATEADD(DAY, -7 * ((DATEPART(WEEKDAY, GETDATE()) % 7) - 1), TRT2.Record_Date2) AS DATE) AS Record_Date3
FROM Trend_T t3
JOIN TRT2 ON TRT2.ID = t3.ID
WHERE t3.Record_Date BETWEEN CAST(DATEADD(DAY, -7 * ((DATEPART(WEEKDAY, GETDATE()) % 7) - 1), TRT2.Record_Date2) AS DATE) AND dateadd(DAY, -1, TRT2.Record_Date2)
GROUP BY t3.ID, TRT2.Record_Date2 
)
SELECT TRT1.ID,
Reading_wkexp Reading_crnt,
Reading_wk1,
Reading_wk2,
Reading_wk3,       
TRT1.Record_Date AS Record_Date_wk1,
TRT2.Record_Date2 AS Record_Date2_wk2,
TRT3.Record_Date3 AS Record_Date_wk3,
CASE
WHEN Reading_wkexp > Reading_wk1 THEN 'Up'
WHEN Reading_wkexp < Reading_wk1 THEN 'Down'
WHEN Reading_wkexp = Reading_wkexp THEN '-'
END Wk1_Trend,
CASE
WHEN Reading_wk1 > Reading_wk2 THEN 'Up'
WHEN Reading_wk1 < Reading_wk2 THEN 'Down'
WHEN Reading_wk1 = Reading_wk1 THEN '-'
END Wk2_Trend,
CASE
WHEN Reading_wk2 > Reading_wk3 THEN 'Up'
WHEN Reading_wk2 < Reading_wk3 THEN 'Down'
WHEN Reading_wk2 = Reading_wk3 THEN '-'
END Wk3_Trend
FROM  TRT1 
JOIN TRT2 ON TRT1.ID = TRT2.ID
JOIN TRT3 ON TRT2.ID = TRT3.ID
JOIN TRTx ON TRT1.ID = TRTx.ID
;

下面是用于创建示例数据的 SQL

CREATE TABLE Trend_T (ID Int, Reading Float null, Record_Date Datetime)
Insert into Trend_T (ID, Reading, Record_Date )
select 1, 0, '2018-09-19' union all
select 1, 27, '2018-09-18' union all
select 1, 0, '2018-09-17' union all
select 1, 0, '2018-09-16' union all
select 1, 0, '2018-09-15' union all
select 1, 0, '2018-09-14' union all
select 1, 7, '2018-09-13' union all
select 1, 12, '2018-09-12' union all
select 1, 0, '2018-09-11' union all
select 1, 0, '2018-09-10' union all
select 1, 17, '2018-09-09' union all
select 1, 22, '2018-09-08' union all
select 1, 0, '2018-09-07' union all
select 1, 0, '2018-09-06' union all
select 1, 0, '2018-09-05' union all
select 1, 24, '2018-09-04' union all
select 1, 0, '2018-09-03' union all
select 1, 0, '2018-09-02' union all
select 1, 17, '2018-09-01' union all
select 1, 0, '2018-08-31' union all
select 1, 19, '2018-08-30' union all
select 1, 0, '2018-08-29' union all
select 1, 0, '2018-08-28' union all
select 1, 0, '2018-08-27' union all
select 1, 0, '2018-08-26' ;

试试这个,我得到了你预期的结果。我基本上将每周的开始和结束日期保存到临时表中,然后在编译结果时使用它。

SELECT *
INTO #Weeks
FROM (
SELECT WeekType = 0, StartDate = CONVERT(CHAR(10), DATEADD(DAY, (-1) * (DATEPART(WEEKDAY, GETDATE() - 1)), GETDATE()), 101), EndDate = CONVERT(CHAR(10), DATEADD(DAY, 6, DATEADD(DAY, (-1) * (DATEPART(WEEKDAY, GETDATE() - 1)), GETDATE())), 101)
UNION ALL
SELECT WeekType = 1, StartDate = CONVERT(CHAR(10), DATEADD(DAY, (-1) * (DATEPART(WEEKDAY, GETDATE() - 1)) - 7, GETDATE()), 101), EndDate = CONVERT(CHAR(10), DATEADD(DAY, 6, DATEADD(DAY, (-1) * (DATEPART(WEEKDAY, GETDATE() - 1)) - 7, GETDATE())), 101)
UNION ALL
SELECT WeekType = 2, StartDate = CONVERT(CHAR(10), DATEADD(DAY, (-1) * (DATEPART(WEEKDAY, GETDATE() - 1)) - 14, GETDATE()), 101), EndDate = CONVERT(CHAR(10), DATEADD(DAY, 6, DATEADD(DAY, (-1) * (DATEPART(WEEKDAY, GETDATE() - 1)) - 14, GETDATE())), 101)
UNION ALL
SELECT WeekType = 3, StartDate = CONVERT(CHAR(10), DATEADD(DAY, (-1) * (DATEPART(WEEKDAY, GETDATE() - 1)) - 21, GETDATE()), 101), EndDate = CONVERT(CHAR(10), DATEADD(DAY, 6, DATEADD(DAY, (-1) * (DATEPART(WEEKDAY, GETDATE() - 1)) - 21, GETDATE())), 101)
) t
GO
WITH 
TRTx AS (SELECT ((SELECT SUM(t1.Reading) FROM Trend_T t1 WHERE t1.Record_Date BETWEEN (SELECT StartDate FROM #Weeks WHERE WeekType = 1) AND (SELECT EndDate FROM #Weeks WHERE WeekType = 1) AND t1.ID = t0.ID )
* (cast(7 as float)/cast(DATEPART(WEEKDAY,GETDATE()) as float))) Reading_wkexp, 
t0.ID 
FROM Trend_T t0
WHERE t0.Record_Date BETWEEN (SELECT StartDate FROM #Weeks WHERE WeekType = 0) AND (SELECT EndDate FROM #Weeks WHERE WeekType = 0)  
GROUP BY t0.ID
),
TRT1 AS (SELECT SUM(t1.Reading) Reading_wk1, t1.ID 
FROM Trend_T t1
WHERE t1.Record_Date BETWEEN (SELECT StartDate FROM #Weeks WHERE WeekType = 1) AND (SELECT EndDate FROM #Weeks WHERE WeekType = 1) 
GROUP BY t1.ID
),
TRT2 AS (SELECT SUM(t2.Reading) Reading_wk2, t2.ID 
FROM Trend_T t2 
JOIN TRT1 ON TRT1.ID = t2.ID
WHERE t2.Record_Date BETWEEN (SELECT StartDate FROM #Weeks WHERE WeekType = 2) AND (SELECT EndDate FROM #Weeks WHERE WeekType = 2)
GROUP BY t2.ID 
),
TRT3 AS (SELECT SUM(t3.Reading) Reading_wk3, t3.ID 
FROM Trend_T t3
JOIN TRT2 ON TRT2.ID = t3.ID
WHERE t3.Record_Date BETWEEN (SELECT StartDate FROM #Weeks WHERE WeekType = 3) AND (SELECT EndDate FROM #Weeks WHERE WeekType = 3)
GROUP BY t3.ID 
)
SELECT TRT1.ID,
Reading_wkexp Reading_crnt,
Reading_wk1,
Reading_wk2,
Reading_wk3,
CASE
WHEN Reading_wkexp > Reading_wk1 THEN 'Up'
WHEN Reading_wkexp < Reading_wk1 THEN 'Down'
WHEN Reading_wkexp = Reading_wkexp THEN '-'
END Wk1_Trend,
CASE
WHEN Reading_wk1 > Reading_wk2 THEN 'Up'
WHEN Reading_wk1 < Reading_wk2 THEN 'Down'
WHEN Reading_wk1 = Reading_wk1 THEN '-'
END Wk2_Trend,
CASE
WHEN Reading_wk2 > Reading_wk3 THEN 'Up'
WHEN Reading_wk2 < Reading_wk3 THEN 'Down'
WHEN Reading_wk2 = Reading_wk3 THEN '-'
END Wk3_Trend
FROM  TRT1 
JOIN TRT2 ON TRT1.ID = TRT2.ID
JOIN TRT3 ON TRT2.ID = TRT3.ID
JOIN TRTx ON TRT1.ID = TRTx.ID
GO
DROP TABLE #Weeks

我使日期范围的计算复杂化。给出了一些想法并简化了日期范围以获得我的结果。以下是我的解决方案。

WITH 
TRT AS  (SELECT t.ID, t.Reading, t.RECORD_DATE 
FROM Trend_T t
WHERE t.RECORD_DATE = (SELECT max(RECORD_DATE) FROM Trend_T) 
),
TRTx AS (SELECT (SUM(tx.Reading)*(cast(7 as float)/cast(DATEPART(WEEKDAY,GETDATE()) as float))) Reading_wkexp, tx.ID, CAST(DATEADD(DAY, -1 * ((DATEPART(WEEKDAY, GETDATE()) % 7) - 1), GETDATE()) AS DATE) AS Record_Date
FROM Trend_T tx
WHERE tx.Record_Date BETWEEN CAST(DATEADD(DAY, -1 * ((DATEPART(WEEKDAY, GETDATE()) % 7) - 1), GETDATE()) AS DATE) AND (SELECT max(Record_Date) FROM Trend_T) GROUP BY tx.ID
),
TRT1 AS (SELECT SUM(t1.Reading) Reading_wk1, t1.ID, CAST(DATEADD(DAY, -1 * ((DATEPART(WEEKDAY, GETDATE()) % 7) - 1), GETDATE()) AS DATE) AS Record_Date
FROM Trend_T t1
WHERE t1.Record_Date BETWEEN CAST(DATEADD(DAY, -1 * ((DATEPART(WEEKDAY, GETDATE()) % 7) - 1), GETDATE()) AS DATE) AND (SELECT max(Record_Date) FROM Trend_T) GROUP BY t1.ID
),
TRT2 AS (SELECT SUM(t2.Reading) Reading_wk2, t2.ID, CAST(DATEADD(DAY,-1,TRT1.Record_Date)  AS DATE) AS Record_Date2
FROM Trend_T t2 
JOIN TRT1 ON TRT1.ID = t2.ID
WHERE t2.Record_Date BETWEEN CAST(DATEADD(DAY,-7, TRT1.Record_Date) AS DATE) AND CAST(DATEADD(DAY,-1,TRT1.Record_Date)  AS DATE)
GROUP BY t2.ID, TRT1.Record_Date 
),
TRT3 AS (SELECT SUM(t3.Reading) Reading_wk3, t3.ID, CAST(DATEADD(DAY,-8,TRT1.Record_Date) AS DATE) AS Record_Date3
FROM Trend_T t3
JOIN TRT1 ON TRT1.ID = t3.ID
WHERE t3.Record_Date BETWEEN CAST(DATEADD(DAY,-14,TRT1.Record_Date) AS DATE) AND CAST(DATEADD(DAY,-8,TRT1.Record_Date) AS DATE)
GROUP BY t3.ID, TRT1.Record_Date 
),
TRT4 AS (SELECT SUM(t4.Reading) Reading_wk4, t4.ID, CAST(DATEADD(DAY,-15,TRT1.Record_Date) AS DATE) Record_Date4
FROM Trend_T t4
JOIN TRT1 ON TRT1.ID = t4.ID
WHERE t4.Record_Date BETWEEN CAST(DATEADD(DAY,-21,TRT1.Record_Date) AS DATE) AND CAST(DATEADD(DAY,-15,TRT1.Record_Date) AS DATE)
GROUP BY t4.ID, TRT1.Record_Date 
)
SELECT TRT1.ID,
TRT.Reading  AS Reading_crnt,
Reading_wk1,
Reading_wkexp,
Reading_wk2,
Reading_wk3, 
Reading_wk4,      
Cast(Getdate() as Date) AS Record_Date_wk1,
TRT2.Record_Date2 AS Record_Date2_wk2,
TRT3.Record_Date3 AS Record_Date_wk3,
TRT4.Record_Date4 AS Record_Date_wk4,
CASE
WHEN Reading_wkexp > Reading_wk2 THEN 'Up'
WHEN Reading_wkexp < Reading_wk2 THEN 'Down'
WHEN Reading_wkexp = Reading_wk2 THEN '-'
END Wk1_Trend,
CASE
WHEN Reading_wk2 > Reading_wk3 THEN 'Up'
WHEN Reading_wk2 < Reading_wk3 THEN 'Down'
WHEN Reading_wk2 = Reading_wk3 THEN '-'
END Wk2_Trend,
CASE
WHEN Reading_wk3 > Reading_wk4 THEN 'Up'
WHEN Reading_wk3 < Reading_wk4 THEN 'Down'
WHEN Reading_wk3 = Reading_wk4 THEN '-'
END Wk3_Trend
FROM TRT
JOIN TRT1 ON TRT.ID = TRT1.ID
JOIN TRT2 ON TRT1.ID = TRT2.ID
JOIN TRT3 ON TRT2.ID = TRT3.ID
JOIN TRT4 on TRT4.ID = TRT3.ID
JOIN TRTx ON TRT.ID = TRTx.ID
--ORDER BY TRT1.ID
;

相关内容

最新更新