如何 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 来简化子查询,并在需要时在您的查询中多次引用它们。希望这会有所帮助。