如何 return 在子查询中找到列 B 的最大值的行上列 A 的值
How to return the Value from Column A on the row where the Max of Column B is found in a subquery
我有时间序列数据,我正在创建 90 个样本的滚动平均值 window(15 分钟)。然后我想找到每小时最多 15 分钟 window,以便数据按小时分组。但是我还想 return 最长 15 分钟的开始或结束时间戳 window。目前我只是 return 在每个小时开始时输入时间戳。
这是我开始使用的数据示例:
theDate theTime value
4/30/2019 22:47:53 0
4/30/2019 22:47:43 0
4/30/2019 22:47:33 0
4/30/2019 22:47:23 0
4/30/2019 22:47:13 0
4/30/2019 22:47:03 0
4/30/2019 22:46:53 0
4/30/2019 22:46:43 0
我已经尝试 row_number() 并在何处进行过滤,但我认为我没有正确地应用它们,因为有几个嵌套的子查询。
select
min([theDate]) as theDate,
min([theTime]) as theTime,
max([Value]) as maxValue,
max([rolling_avg]) as maxDM,
timeHour as timeHour
from( select [theDate], [theTime], [Value],
avg(windowAvg) over(order by theDate DESC, theTime rows between 90 preceding and current row) as rolling_avg,
datepart(hh,theTime) as timeHour
from (select [theDate], [theTime], [Value], sum([Value]) as windowAvg
from [Data].[dbo].[tOne]
Where ([theDate] > convert(DAte,DATEADD(month, -1, GETDATE())))
group by theDate, theTime, Value
)tOneTemp
)tOneTempTwo
group by theDate, timeHour
order by theDate DESC, theTime DESC
我正在寻找下面的 table 除了 theTime 始终是我计算的每小时分钟数我希望它是 15 分钟内的值 window计算了 MaxDM。
这是我使用当前代码最终得到的示例:
theDate theTime maxValue maxDM timeHour
2019-04-30 22:00:04 508.8 660.643956 22
2019-04-30 21:00:03 1071.3 798.206593 21
2019-04-30 20:00:03 1022.2 817.539560 20
2019-04-30 19:00:04 871.4 574.786813 19
2019-04-30 18:00:04 944.0 670.095604 18
我希望看到的是 "theTime" 反映 "maxValue" window.
的开始
这是我希望看到的示例(*注意时间):
theDate theTime maxValue maxDM timeHour
2019-04-30 22:10:34 508.8 660.643956 22
2019-04-30 21:45:03 1071.3 798.206593 21
2019-04-30 20:12:03 1022.2 817.539560 20
2019-04-30 19:32:04 871.4 574.786813 19
2019-04-30 18:56:04 944.0 670.095604 18
谢谢 Ali,这里是我对您的代码所做的一些修改,以修复一些错误,但是 "TheTimeOfMaxDM" returns as "NULL" 对于所有行。
min([theDate]) as theDate,
min([theTime]) as theTime,
(select top(1) r.[theTime] from RunningAvg15Min r where
r.[theDate]=(select min([theDate]) from RunningAvg15Min) and
r.[theTime]>=(select min([theTime]) from RunningAvg15Min)
and r.rolling_avg=(select max([rolling_avg]) from RunningAvg15Min)) as TheTimeOfMaxDM,
max([KW]) as maxValue,
max([rolling_avg]) as maxDM,
timeHour as timeHour
from RunningAvg15Min
GROUP BY theDate, timeHour
ORDER BY thedate DESC, thetime DESC
我在 CTE 中重写了您的查询,因此我可以再次使用子查询。请检查以下内容:-
所以我在您的查询中添加了另一个名为 TheTimeOfMaxDM 的输出。希望这是你需要的。
;with LastMonthData as (
--get the data for the last month, and sum value if same time stamp is recorded (this is not logical)
select [theDate], [theTime], [Value], sum([Value]) as windowAvg
from [tOne]
Where ([theDate] > convert(Date,DATEADD(month, -1, '2019-05-3')))--changed this to match the data provided.
group by theDate, theTime, Value
),
RunningAvg15Min as (
select [theDate], [theTime], [Value],
avg(windowAvg) over(order by theDate DESC, theTime rows between 90 preceding and current row) as rolling_avg,
datepart(hh,theTime) as timeHour
from LastMonthData
),DataSetGrouping as (
select
min([theDate]) as theDate,
min([theTime]) as theTime,
min(datepart(hh,theTime)) as timeHour,
max([Value]) as maxValue,
max([rolling_avg]) as maxDM
from RunningAvg15Min
GROUP BY
DATEPART(YEAR, TheDate),
DATEPART(MONTH, TheDate),
DATEPART(DAY, TheDate),
DATEPART(HOUR, TheTime),
(DATEPART(MINUTE, TheTime) / 60) ---change the 60 to 15, to change the grouping from per hour to per 15min
)
select * ,
(select top(1) r.[theTime] from RunningAvg15Min r where
r.[theDate]=theDate
and r.[theTime]>=theTime
and r.rolling_avg=maxDM
order by r.[theDate],r.[theTime]
) [TheTimeOfMaxDM]
from DataSetGrouping
ORDER BY thedate DESC, thetime DESC
另一个注意事项,我不知道你是否需要这个,但如果你想按 15 分钟分组,你可以在分组部分使用下面的内容
GROUP BY
DATEPART(YEAR, TheDate),
DATEPART(MONTH, TheDate),
DATEPART(DAY, TheDate),
DATEPART(HOUR, TheTime),
(DATEPART(MINUTE, TheTime) / 15)
我会尝试验证一个观点,让我们以下面的输出行为例:-
theDate theTime Value rolling_avg timeHour
2019-04-07 17:20:49.0000000 398.3 314.499999999997 17
在 2019-04-07 的 17 和 18 之间,最大值 rolling_avg 为 314.499999999997,而该最大值的时间为 17:20:49.0000000,我们可以看到正在替换最后一个cte 的一部分具有以下内容:-
select * from RunningAvg15Min where rolling_avg between 314 and 315
and thedate='2019-04-07' and theTime between '17:00:00' and '18:00:00'
产出
theDate theTime Value rolling_avg timeHour
2019-04-07 17:20:49.0000000 398.3 314.499999999997 17
总结一下我的回答,您可以使用我编写的查询中的 CTE 来简化子查询,并在需要时在您的查询中多次引用它们。希望这会有所帮助。
我有时间序列数据,我正在创建 90 个样本的滚动平均值 window(15 分钟)。然后我想找到每小时最多 15 分钟 window,以便数据按小时分组。但是我还想 return 最长 15 分钟的开始或结束时间戳 window。目前我只是 return 在每个小时开始时输入时间戳。
这是我开始使用的数据示例:
theDate theTime value
4/30/2019 22:47:53 0
4/30/2019 22:47:43 0
4/30/2019 22:47:33 0
4/30/2019 22:47:23 0
4/30/2019 22:47:13 0
4/30/2019 22:47:03 0
4/30/2019 22:46:53 0
4/30/2019 22:46:43 0
我已经尝试 row_number() 并在何处进行过滤,但我认为我没有正确地应用它们,因为有几个嵌套的子查询。
select
min([theDate]) as theDate,
min([theTime]) as theTime,
max([Value]) as maxValue,
max([rolling_avg]) as maxDM,
timeHour as timeHour
from( select [theDate], [theTime], [Value],
avg(windowAvg) over(order by theDate DESC, theTime rows between 90 preceding and current row) as rolling_avg,
datepart(hh,theTime) as timeHour
from (select [theDate], [theTime], [Value], sum([Value]) as windowAvg
from [Data].[dbo].[tOne]
Where ([theDate] > convert(DAte,DATEADD(month, -1, GETDATE())))
group by theDate, theTime, Value
)tOneTemp
)tOneTempTwo
group by theDate, timeHour
order by theDate DESC, theTime DESC
我正在寻找下面的 table 除了 theTime 始终是我计算的每小时分钟数我希望它是 15 分钟内的值 window计算了 MaxDM。
这是我使用当前代码最终得到的示例:
theDate theTime maxValue maxDM timeHour
2019-04-30 22:00:04 508.8 660.643956 22
2019-04-30 21:00:03 1071.3 798.206593 21
2019-04-30 20:00:03 1022.2 817.539560 20
2019-04-30 19:00:04 871.4 574.786813 19
2019-04-30 18:00:04 944.0 670.095604 18
我希望看到的是 "theTime" 反映 "maxValue" window.
的开始这是我希望看到的示例(*注意时间):
theDate theTime maxValue maxDM timeHour
2019-04-30 22:10:34 508.8 660.643956 22
2019-04-30 21:45:03 1071.3 798.206593 21
2019-04-30 20:12:03 1022.2 817.539560 20
2019-04-30 19:32:04 871.4 574.786813 19
2019-04-30 18:56:04 944.0 670.095604 18
谢谢 Ali,这里是我对您的代码所做的一些修改,以修复一些错误,但是 "TheTimeOfMaxDM" returns as "NULL" 对于所有行。
min([theDate]) as theDate,
min([theTime]) as theTime,
(select top(1) r.[theTime] from RunningAvg15Min r where
r.[theDate]=(select min([theDate]) from RunningAvg15Min) and
r.[theTime]>=(select min([theTime]) from RunningAvg15Min)
and r.rolling_avg=(select max([rolling_avg]) from RunningAvg15Min)) as TheTimeOfMaxDM,
max([KW]) as maxValue,
max([rolling_avg]) as maxDM,
timeHour as timeHour
from RunningAvg15Min
GROUP BY theDate, timeHour
ORDER BY thedate DESC, thetime DESC
我在 CTE 中重写了您的查询,因此我可以再次使用子查询。请检查以下内容:- 所以我在您的查询中添加了另一个名为 TheTimeOfMaxDM 的输出。希望这是你需要的。
;with LastMonthData as (
--get the data for the last month, and sum value if same time stamp is recorded (this is not logical)
select [theDate], [theTime], [Value], sum([Value]) as windowAvg
from [tOne]
Where ([theDate] > convert(Date,DATEADD(month, -1, '2019-05-3')))--changed this to match the data provided.
group by theDate, theTime, Value
),
RunningAvg15Min as (
select [theDate], [theTime], [Value],
avg(windowAvg) over(order by theDate DESC, theTime rows between 90 preceding and current row) as rolling_avg,
datepart(hh,theTime) as timeHour
from LastMonthData
),DataSetGrouping as (
select
min([theDate]) as theDate,
min([theTime]) as theTime,
min(datepart(hh,theTime)) as timeHour,
max([Value]) as maxValue,
max([rolling_avg]) as maxDM
from RunningAvg15Min
GROUP BY
DATEPART(YEAR, TheDate),
DATEPART(MONTH, TheDate),
DATEPART(DAY, TheDate),
DATEPART(HOUR, TheTime),
(DATEPART(MINUTE, TheTime) / 60) ---change the 60 to 15, to change the grouping from per hour to per 15min
)
select * ,
(select top(1) r.[theTime] from RunningAvg15Min r where
r.[theDate]=theDate
and r.[theTime]>=theTime
and r.rolling_avg=maxDM
order by r.[theDate],r.[theTime]
) [TheTimeOfMaxDM]
from DataSetGrouping
ORDER BY thedate DESC, thetime DESC
另一个注意事项,我不知道你是否需要这个,但如果你想按 15 分钟分组,你可以在分组部分使用下面的内容
GROUP BY
DATEPART(YEAR, TheDate),
DATEPART(MONTH, TheDate),
DATEPART(DAY, TheDate),
DATEPART(HOUR, TheTime),
(DATEPART(MINUTE, TheTime) / 15)
我会尝试验证一个观点,让我们以下面的输出行为例:-
theDate theTime Value rolling_avg timeHour
2019-04-07 17:20:49.0000000 398.3 314.499999999997 17
在 2019-04-07 的 17 和 18 之间,最大值 rolling_avg 为 314.499999999997,而该最大值的时间为 17:20:49.0000000,我们可以看到正在替换最后一个cte 的一部分具有以下内容:-
select * from RunningAvg15Min where rolling_avg between 314 and 315
and thedate='2019-04-07' and theTime between '17:00:00' and '18:00:00'
产出
theDate theTime Value rolling_avg timeHour
2019-04-07 17:20:49.0000000 398.3 314.499999999997 17
总结一下我的回答,您可以使用我编写的查询中的 CTE 来简化子查询,并在需要时在您的查询中多次引用它们。希望这会有所帮助。