我有这个数据集,我在每个班次创建一个报告来显示每小时的特定活动。例如:班次从7到15,因此报告将为: 7:00-15移动 8:00-18步
此报告包含数周和数天的过滤器,因为目的是让用户查看其轮班表现。
但是,我想将特定时间段内的活动与过去10周中同一天的同一天进行比较。例如:
我在周二的7:00时有15次移动,我想将其与过去10周中周二的7:00的平均移动次数进行比较。
我将如何在SQL中获得它! :-)
答案 0 :(得分:0)
这可能会使您朝正确的方向前进。鉴于您尚未声明您的数据结构,因此我自由地假设可能是这样。
您可以在SSMS中运行以下命令来自己查看/修改结果。
首先,我创建了一个表变量来模拟假定的数据。
-- Create a dummy "shift" table --
DECLARE @shifts TABLE ( shift_id INT IDENTITY ( 1, 1 ) PRIMARY KEY, shift_date DATETIME, shift_moves INT );
然后我插入了一些虚拟数据。为了节省时间和简化起见,我在过去的十个星期中坚持使用星期二。
-- Insert ten weeks of Tuesdays --
INSERT INTO @shifts ( shift_date, shift_moves ) VALUES
( '11/06/2018 07:10:00', 5 )
, ( '11/13/2018 07:08:00', 12 )
, ( '11/20/2018 07:00:00', 14 )
, ( '11/27/2018 07:20:00', 15 )
, ( '12/04/2018 07:35:00', 12 )
, ( '12/11/2018 07:18:00', 11 )
, ( '12/18/2018 07:16:00', 10 )
, ( '12/25/2018 07:00:00', 12 )
, ( '01/01/2019 07:00:00', 13 )
, ( '01/08/2019 07:22:00', 15 );
表变量@shifts现在包含以下数据:
+----------+-------------------------+-------------+
| shift_id | shift_date | shift_moves |
+----------+-------------------------+-------------+
| 1 | 2018-11-06 07:10:00.000 | 5 |
| 2 | 2018-11-13 07:08:00.000 | 12 |
| 3 | 2018-11-20 07:00:00.000 | 14 |
| 4 | 2018-11-27 07:20:00.000 | 15 |
| 5 | 2018-12-04 07:35:00.000 | 12 |
| 6 | 2018-12-11 07:18:00.000 | 11 |
| 7 | 2018-12-18 07:16:00.000 | 10 |
| 8 | 2018-12-25 07:00:00.000 | 12 |
| 9 | 2019-01-01 07:00:00.000 | 13 |
| 10 | 2019-01-08 07:22:00.000 | 15 |
+----------+-------------------------+-------------+
我创建了一些可以传递给存储过程的参数。
-- What date are we looking at? --
DECLARE @date DATETIME = '01/08/2019';
-- How many weeks back to compare? --
DECLARE @weeks_back INT = -10;
*记住:要向后看,@ weeks_back 必须为负数。 在生产中,您将对此进行检查/处理。
接下来,我创建了两个局部变量,以帮助简化查询时使用的日期/时间。
-- Create variables for the start and end times for simplicity --
DECLARE
@sDT DATETIME = CAST( CONVERT( VARCHAR(10), @date, 101 ) + ' 00:00:00' AS DATETIME ),
@eDT DATETIME = CAST( CONVERT( VARCHAR(10), @date, 101 ) + ' 23:59:59' AS DATETIME );
然后,只需使用CROSS APPLY查询数据以获取所需结果即可。
使用CROSS APPLY允许我查询所需时间范围(@weeks_back)的第二个轮班数据子集,该子集与查询的主要记录(在本例中为shift_date为01/08/2019)相关。
-- Get resultset --
SELECT
DATEPART( hh, shift_date ) AS [shift_hour]
, DATENAME( dw, s.shift_date ) AS [shift_day]
, CONVERT( VARCHAR(10), s.shift_date, 101 ) AS [shift_date]
, s.shift_moves
, shift_avg.shift_average
FROM @shifts AS s
CROSS APPLY (
SELECT
AVG( a.shift_moves ) AS [shift_average]
FROM @shifts a
WHERE
-- restrict to the current hour.
DATEPART( HH, a.shift_date ) = DATEPART( HH, s.shift_date )
-- restrict to the current day of the week.
AND DATEPART( DW, a.shift_date ) = DATEPART( DW, s.shift_date )
-- compare against the desired time period / weeks back.
AND a.shift_date BETWEEN DATEADD( WW, @weeks_back, CAST( CONVERT( VARCHAR(10), s.shift_date, 101 ) AS DATETIME ) ) AND a.shift_date
) AS shift_avg
WHERE
s.shift_date BETWEEN @sDT AND @eDT
ORDER BY
s.shift_date;
哪个返回以下结果集:
+------------+-----------+------------+-------------+---------------+
| shift_hour | shift_day | shift_date | shift_moves | shift_average |
+------------+-----------+------------+-------------+---------------+
| 7 | Tuesday | 01/08/2019 | 15 | 11 |
+------------+-----------+------------+-------------+---------------+
我希望这能帮助您朝着想要的方向前进,@ Aron。