我正在研究一种T-SQL查询,以获取过去三周的周日至周六的读数总和以及当前周的预测值。目标是比较每周的值以显示趋势。
当前周的预测计算是从上一个星期日开始的读数总和*(一周的7 /天)
例如:(27 *(7/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' ;
答案 0 :(得分:1)
尝试一下,我得到您的预期结果。我基本上将每周的开始日期和结束日期保存到临时表中,然后在编译结果时使用它。
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
答案 1 :(得分:0)
我复杂了日期范围的计算。给了一些想法,并简化了日期范围以获得我的结果。下面是我的解决方案。
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
;