我想取多行表的平均值并将它们插入视图中:
我的表:
示例数据:
Date | Period | Price
---------+--------+---------
07-12-17 | 47 | 10
07-12-17 | 48 | 20
07-12-17 | 1 | 30
07-12-17 | 2 | 40
07-12-17 | 3 | 50
07-12-17 | 4 | 60
07-12-17 | 5 | 70
07-12-17 | 6 | 80
07-12-17 | 7 | 10
07-12-17 | 8 | 10
07-12-17 | 9 | 10
07-12-17 | 10 | 10
07-12-17 | 11 | 20
07-12-17 | 12 | 20
07-12-17 | 13 | 20
07-12-17 | 14 | 20
我的期间是半小时从1-48开始,我想取8个期间的平均价格,并将该价格分配给该集合中的所有8个期间。由于时差,我从半小时47开始而不是1:
间隔:
[48-6], [7-14], [15-22], [23-30], [31-38], [39-46]
我希望生成的视图看起来像:
Date | Period | Price
---------+--------+---------
07-12-17 | 47 | 45
07-12-17 | 48 | 45
07-12-17 | 1 | 45
07-12-17 | 2 | 45
07-12-17 | 3 | 45
07-12-17 | 4 | 45
07-12-17 | 5 | 45
07-12-17 | 6 | 45
07-12-17 | 7 | 15
07-12-17 | 8 | 15
07-12-17 | 9 | 15
07-12-17 | 10 | 15
07-12-17 | 11 | 15
07-12-17 | 12 | 15
07-12-17 | 13 | 15
07-12-17 | 14 | 15
我无法提出完整的查询,但我认为它必须是GROUP BY并且可能带有HAVING Statement。
希望你能帮忙!
答案 0 :(得分:1)
使用窗口功能可以非常轻松有效地完成。
示例数据
DECLARE @T TABLE (dt datetime2(0), Period int, Price money);
INSERT INTO @T VALUES
('2017-12-06', 39, 90),
('2017-12-06', 40, 90),
('2017-12-06', 41, 90),
('2017-12-06', 42, 90),
('2017-12-06', 43, 90),
('2017-12-06', 44, 90),
('2017-12-06', 45, 90),
('2017-12-06', 46, 90),
('2017-12-06', 47, 10),
('2017-12-06', 48, 20),
('2017-12-07', 1, 30),
('2017-12-07', 2, 40),
('2017-12-07', 3, 50),
('2017-12-07', 4, 60),
('2017-12-07', 5, 70),
('2017-12-07', 6, 80),
('2017-12-07', 7, 10),
('2017-12-07', 8, 10),
('2017-12-07', 9, 10),
('2017-12-07', 10, 10),
('2017-12-07', 11, 20),
('2017-12-07', 12, 20),
('2017-12-07', 13, 20),
('2017-12-07', 14, 20),
('2017-12-07', 15, 40),
('2017-12-07', 16, 40),
('2017-12-07', 17, 40),
('2017-12-07', 18, 40),
('2017-12-07', 19, 30),
('2017-12-07', 20, 30),
('2017-12-07', 21, 30),
('2017-12-07', 22, 30);
<强>查询强>
SELECT
dt
,Period
,Price
,DATEADD(minute, (Period-1)*30 + 60, dt) as d2
,DATEDIFF(hour, '2001-01-01', DATEADD(minute, (Period-1)*30 + 60, dt)) / 4 as d3
,AVG(Price) OVER (PARTITION BY
DATEDIFF(hour, '2001-01-01', DATEADD(minute, (Period-1)*30 + 60, dt)) / 4) AS AvgPrice
FROM @T AS MyTable
ORDER BY dt, Period;
我在输出中包含了中间结果d2
和d3
,以帮助理解PARTITION BY
中的公式。
<强>结果强>
+---------------------+--------+-------+---------------------+-------+----------+
| dt | Period | Price | d2 | d3 | AvgPrice |
+---------------------+--------+-------+---------------------+-------+----------+
| 2017-12-06 00:00:00 | 39 | 90.00 | 2017-12-06 20:00:00 | 37103 | 90.00 |
| 2017-12-06 00:00:00 | 40 | 90.00 | 2017-12-06 20:30:00 | 37103 | 90.00 |
| 2017-12-06 00:00:00 | 41 | 90.00 | 2017-12-06 21:00:00 | 37103 | 90.00 |
| 2017-12-06 00:00:00 | 42 | 90.00 | 2017-12-06 21:30:00 | 37103 | 90.00 |
| 2017-12-06 00:00:00 | 43 | 90.00 | 2017-12-06 22:00:00 | 37103 | 90.00 |
| 2017-12-06 00:00:00 | 44 | 90.00 | 2017-12-06 22:30:00 | 37103 | 90.00 |
| 2017-12-06 00:00:00 | 45 | 90.00 | 2017-12-06 23:00:00 | 37103 | 90.00 |
| 2017-12-06 00:00:00 | 46 | 90.00 | 2017-12-06 23:30:00 | 37103 | 90.00 |
| 2017-12-06 00:00:00 | 47 | 10.00 | 2017-12-07 00:00:00 | 37104 | 45.00 |
| 2017-12-06 00:00:00 | 48 | 20.00 | 2017-12-07 00:30:00 | 37104 | 45.00 |
| 2017-12-07 00:00:00 | 1 | 30.00 | 2017-12-07 01:00:00 | 37104 | 45.00 |
| 2017-12-07 00:00:00 | 2 | 40.00 | 2017-12-07 01:30:00 | 37104 | 45.00 |
| 2017-12-07 00:00:00 | 3 | 50.00 | 2017-12-07 02:00:00 | 37104 | 45.00 |
| 2017-12-07 00:00:00 | 4 | 60.00 | 2017-12-07 02:30:00 | 37104 | 45.00 |
| 2017-12-07 00:00:00 | 5 | 70.00 | 2017-12-07 03:00:00 | 37104 | 45.00 |
| 2017-12-07 00:00:00 | 6 | 80.00 | 2017-12-07 03:30:00 | 37104 | 45.00 |
| 2017-12-07 00:00:00 | 7 | 10.00 | 2017-12-07 04:00:00 | 37105 | 15.00 |
| 2017-12-07 00:00:00 | 8 | 10.00 | 2017-12-07 04:30:00 | 37105 | 15.00 |
| 2017-12-07 00:00:00 | 9 | 10.00 | 2017-12-07 05:00:00 | 37105 | 15.00 |
| 2017-12-07 00:00:00 | 10 | 10.00 | 2017-12-07 05:30:00 | 37105 | 15.00 |
| 2017-12-07 00:00:00 | 11 | 20.00 | 2017-12-07 06:00:00 | 37105 | 15.00 |
| 2017-12-07 00:00:00 | 12 | 20.00 | 2017-12-07 06:30:00 | 37105 | 15.00 |
| 2017-12-07 00:00:00 | 13 | 20.00 | 2017-12-07 07:00:00 | 37105 | 15.00 |
| 2017-12-07 00:00:00 | 14 | 20.00 | 2017-12-07 07:30:00 | 37105 | 15.00 |
| 2017-12-07 00:00:00 | 15 | 40.00 | 2017-12-07 08:00:00 | 37106 | 35.00 |
| 2017-12-07 00:00:00 | 16 | 40.00 | 2017-12-07 08:30:00 | 37106 | 35.00 |
| 2017-12-07 00:00:00 | 17 | 40.00 | 2017-12-07 09:00:00 | 37106 | 35.00 |
| 2017-12-07 00:00:00 | 18 | 40.00 | 2017-12-07 09:30:00 | 37106 | 35.00 |
| 2017-12-07 00:00:00 | 19 | 30.00 | 2017-12-07 10:00:00 | 37106 | 35.00 |
| 2017-12-07 00:00:00 | 20 | 30.00 | 2017-12-07 10:30:00 | 37106 | 35.00 |
| 2017-12-07 00:00:00 | 21 | 30.00 | 2017-12-07 11:00:00 | 37106 | 35.00 |
| 2017-12-07 00:00:00 | 22 | 30.00 | 2017-12-07 11:30:00 | 37106 | 35.00 |
+---------------------+--------+-------+---------------------+-------+----------+
答案 1 :(得分:0)
下面的代码示例应该让您接近您需要的位置。我不确定你的问题是如何计划建立你的小组的。如果您使用视图,您肯定希望使用交叉申请。这可以通过存储过程更简单地完成。有关“交叉申请”的详细信息,请参阅L部分,此处为https://docs.microsoft.com/en-us/sql/t-sql/queries/from-transact-sql。
CREATE VIEW MyTableAveragePrices
AS
SELECT mt.Date, mt.Period, mtAverageGroup.AveragePrice,
CASE
WHEN mtAvg.Period IN () THEN 'Period Group 1'
WHEN mtAvg.Period IN () THEN 'Period Group 2'
END AS PeriodGroup
FROM MyTable mt
CROSS APPLY
(
SELECT
AVERAGE(mtAvg.Price) AveragePrice,
CASE
WHEN mtAvg.Period IN () THEN 'Period Group 1'
WHEN mtAvg.Period IN () THEN 'Period Group 2'
END AS PeriodGroup
FROM MyTable mtAvg
WHERE
mt.PeriodGroup = PeriodGroup
GROUP BY
CASE
WHEN mtAvg.Period IN () THEN 'Period Group 1'
WHEN mtAvg.Period IN () THEN 'Period Group 2'
END
) mtAverageGroup
GO