【问题标题】:SQL query - Find daily Min, Max and times when the Min and Max values occurredSQL 查询 - 查找每日最小值、最大值以及最小值和最大值出现的时间
【发布时间】:2015-07-11 02:52:21
【问题描述】:

我有一张看起来像这样的桌子:

_Datetime           | Value
2015-05-01 06:00:00 | 12.3
2015-05-01 06:20:00 | 12.5
2015-05-01 06:40:00 | 12.3
2015-05-01 07:00:00 | 13.5
2015-05-01 07:20:00 | 14.5
2015-05-01 07:40:00 | 14.3
2015-05-01 08:00:00 | 18.2
2015-05-01 08:20:00 | 15.0
2015-05-01 08:40:00 | 15.0

2015-05-02 06:00:00 | 19.2
2015-05-02 06:20:00 | 7.3
2015-05-02 06:40:00 | 11.4
2015-05-02 07:00:00 | 9.5
2015-05-02 07:20:00 | 7.6
2015-05-02 07:40:00 | 6.6
2015-05-02 08:00:00 | 10.4
2015-05-02 08:20:00 | 19.3
2015-05-02 08:40:00 | 15.4

2015-05-03 06:00:00 | 8.7
2015-05-03 06:20:00 | 8.6
2015-05-03 06:40:00 | 8.6
2015-05-03 07:00:00 | 21.5
2015-05-03 07:20:00 | 12.4
2015-05-03 07:40:00 | 7.3
2015-05-03 08:00:00 | 10.8
2015-05-03 08:20:00 | 12.5
2015-05-03 08:40:00 | 10.6

我想:

-选择每天的最小值、最大值和平均值

-选择最小值和最大值发生的时间(我只想选择一行 - 第一行)

_Date      | _Min  |  _MinTime  |  _Max  |  _MaxTime  |  Avg    |
2015-05-01 | 12.3  |  06:00:00  |  18.2  |  08:00:00  |  14.18  |
2015-05-02 |  6.6  |  07:40:00  |  19.3  |  08:20:00  |  11.86  |
2015-05-03 |  7.3  |  07:40:00  |  21.5  |  07:00:00  |  11.22  |

我可以轻松获得最小值、最大值和平均值,但我被时间卡住了。

【问题讨论】:

  • 您使用的是哪个数据库? mysql还是sqlserver?
  • 请显示您目前的查询。
  • 我使用的是 SQL Server 2008 R2。
  • 查看 group by 并有 sql 子句,然后返回您对 sql 的最佳尝试并发布它。
  • 我对 SQL 很陌生,所以我这样做的方式可能不是最好的方式。我创建了 3 个视图:首先是获取最小值、最大值和平均值,并将它们按日、月和年分组。第二个获取每天的最小值时间,第三个获取每天的最大值时间。我现在遇到的问题是,如果一天的表格中有超过一个最小值或最大值,我的视图会列出所有这些值。我还希望所有内容都集中在一个视图中。

标签: sql-server


【解决方案1】:

试试这个 - 应该每天只返回一组值。 (已编辑 - 添加平均值,按照 cmets 中的建议对其进行四舍五入)。

; with cte as (
select *
    , cast (_datetime as date) as [DateFormat]
    , cast (_datetime as time) as [TimeFormat]
    , row_number() over (partition by cast (_datetime as date) order by Value, _datetime) RNmin
    , row_number() over (partition by cast (_datetime as date) order by Value desc, _datetime) RNmax
    , Avg(value) over (partition by cast (_datetime as date)) as AvgVal
from MyTable
)
select a.DateFormat, a.value as MinValue, a.TimeFormat as MinTime
     , b.value as MaxValue, b.TimeFormat as MaxTime
     , cast(a.AvgVal as decimal(5,2)) as AverageValue
from Cte a
join cte b
on a.DateFormat = B.Dateformat and a.RNmin = 1 and b.RNmax = 1

【讨论】:

  • 这会为所有日期返回相同的 _MinTime 和 _MaxTime。查看上面的输出,这不是 OP 想要的。
  • 是的 - 这是我最初发布时的错误。它现在应该可以工作了,@nepalirookie。我按错误的列排序;对此感到抱歉。
  • 现在应该可以工作了。只是一个建议,OP 正在寻找两位小数的平均值。所以,我只会将该平均字段转换为十进制 (5,2)。 sqlfiddle.com/#!3/8baed/13/0
【解决方案2】:
SELECT x.*
     , min.datetime min_time
     , max.datetime max_time
  FROM 
     ( SELECT DATE(datetime) date
            , MIN(value) min_value
            , MAX(value) max_value
            , AVG(value) 
         FROM my_table 
        GROUP 
           BY DATE(datetime)
     ) x
  JOIN my_table min
    ON DATE(min.datetime) = x.date
   AND min.value = x.min_value
  JOIN my_table max
    ON DATE(max.datetime) = x.date
   AND max.value = x.max_value;

【讨论】:

  • 这个查询完成了我需要它做的事情,但仍然列出了 2015-05-01 的多个最小值
  • 它返回 2015-05-01 的多个列,因为您在两个不同的时间有两个最小值 12.3。 2015-05-01 06:00:00 | 12.3 和 2015-05-01 06:40:00 | 12.3.
  • 正确。最小值在 2015.03.01 出现了两次,但我希望查询只返回第一个。
【解决方案3】:

--

this will get you the mins.....
create table table1  
(_date datetime,
value float);

insert into table1 values (
'2015-05-01 06:00:00',  12.3)
,('2015-05-01 06:20:00',12.5)
<('2015-05-02 06:00:00', 19.2)
,('2015-05-02 06:20:00', 7.3)

select * from
 ( select min(value) as min1 ,cast(_date as date) as date1 from table1 group by cast(_date as date) )
 as i1
inner join
(select cast(_date as date) _date1,value, cast(_date as time) _time1 from table1)  as i2

on i1.min1= i2.value and
cast(i2._date1 as date)= i1.date1

【讨论】:

  • 有人在没有解释的情况下扣分的速度给我留下了深刻的印象。
  • 点击按钮比打字容易很多,所以不要太惊讶。
猜你喜欢
  • 1970-01-01
  • 2012-09-16
  • 2017-04-20
  • 1970-01-01
  • 2022-10-26
  • 2015-03-28
  • 1970-01-01
  • 1970-01-01
  • 2019-02-25
相关资源
最近更新 更多