【问题标题】:Efficiently find "record high" values有效地找到“创纪录的”值
【发布时间】:2014-12-17 16:46:45
【问题描述】:

我试图找出一种有效的方法来从一组数据中识别出一组“创纪录的高”值。这比仅仅找到最大值更复杂,因为我想找到在记录它们时是最大值/记录高值的所有值。因此,为了尽可能简化问题,想象一个模型/数据库表,如下所示:

Temperatures(date, value)

具有如下值:

*1/1/2001: 79
*1/2/2001: 81
1/3/2001: 81
1/4/2001: 80
*1/5/2001: 82
1/6/2001: 81
*1/7/2001: 90

我正在尝试查找有助于将上面带星号 ("*") 的记录识别为“记录”的查询。 rails finder 或 raw sql 语句都可以正常工作。到目前为止,我得到的最好的结果是一个查询,它会告诉我给定的值是否是一个记录,但这并不能很好地扩展。

【问题讨论】:

  • 我不认为它可以很容易地转换为 SQL,但是根据日期排序并在保持最大值的同时进行迭代应该可以解决问题。如果您的数据太大,可能不可行,您的数据规模是多少?您需要多久执行一次此查询?
  • SELECT [Date], MAX([Value]) FROM Temperatures GROUP BY [Date] 怎么样?我正在对您的数据做出假设,这就是为什么这是评论,而不是答案

标签: sql ruby-on-rails algorithm ruby-on-rails-4 query-optimization


【解决方案1】:

您可以使用not exists 选择不存在具有更高值和更早日期的另一行的行

select date, value
from mytable t1
where not exists (
    select 1 from mytable t2
    where t2.value >= t1.value
    and t2.date < t1.date
)

【讨论】:

    【解决方案2】:

    只是一个 group by 就可以了。试试这个

    SELECT MAX(Temperature), Date
    FROM dbo.Temperatures
    GROUP BY Date
    

    【讨论】:

      【解决方案3】:

      在标准 SQL 中:

      with temp (d, t, r) as                             
      (select d, t, row_number() over (order by d)       
       from t),                                    
           data (d, t, r) as                             
      (select d, t, r                                    
       from   temp                                       
       where  r = 1                                      
       union  all                                        
       select case when t.t > d.t then t.d else d.d end, 
              case when t.t > d.t then t.t else d.t end, 
              t.r                                        
       from   temp t                                     
       inner  join data d on d.r+1 = t.r)                
      select min(d), min(t)                              
      from   data                                        
      group  by d, t    
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-08
        • 2023-03-09
        • 1970-01-01
        • 2012-03-05
        • 2014-12-18
        • 1970-01-01
        • 2023-03-20
        • 1970-01-01
        相关资源
        最近更新 更多