【问题标题】:simple sql (i hope!)简单的sql(我希望!)
【发布时间】:2019-04-08 13:18:23
【问题描述】:

给定一个类似这样的数据集:

ccy | time | fxrate
GBP | 11   | 1.2
EUR | 21   | 1.4
CHF | 9    | 3.1
GBP | 15   | 1.1
EUR | 20   | 1.5
CHF | 1    | 3.0
CHF | 7    | 3.0
GBP | 20   | 1.9

我想获取每个 ccy 的最新 fxrates(按“时间”):

ccy | time | fxrate
GBP | 20   | 1.9
EUR | 21   | 1.4
CHF | 9    | 3.1

是否可以通过单个 sql 查询获取这些数据?我的技能让我失望了。我想我需要 GROUP BY ccy ..?最大(时间)在哪里 ..?限制 1 ..?救命!

[编辑] 使用 postgresql

【问题讨论】:

标签: sql postgresql group-by greatest-n-per-group


【解决方案1】:

是的,您可以将group by 仅用于最大 fxrate,但在您的情况下,您需要一个相关的子查询:

select t.*
from table t
where t.fxrate = (select max(t1.fxrate) from table t1 where t1.ccy = t.ccy);

在 postgresql 中你可以这样做:

select distinct on (ccy) *
from table t
order by t.fxrate desc;

【讨论】:

  • 它可以工作(第一个版本),但我正在努力阻止它进行全表扫描,所以它很慢。现在开始使用索引。
  • @pomo 尝试第二个查询,因为它比第一个更好,但将顺序更改为 order by ccy, time desc - 这应该既正确又快速。
  • 谢谢。这似乎行得通。虽然很慢。它正在执行全表扫描。我猜我缺少索引。
【解决方案2】:

row_number 可能会有所帮助

select * from (select *,row_number()over(partition by ccy order by time desc) rn
from table_name
) a where a.rn=1

【讨论】:

  • 谢谢,但速度非常慢。即使我(认为)我有正确的索引,它仍在进行全表扫描。
【解决方案3】:

您还可以在子查询中使用内连接来获取 ccy 的最大时间组

select m.ccy, m.time, m.fxrate 
from my_table  m
inner join  (
  select ccy, max(time) max_time  
  from my_table  
  group by ccy
) t on t.ccy = m.ccy and t.max_time = m.time

【讨论】:

    【解决方案4】:
    select ccy , time ,fxrate 
    from mytable
    Inner join(SELECT max(time) maxtime, ccy
                FROM  mytable
                group by ccy ) MAXCCY on maxccy.maxtime = mytable.time and MAXCCY.ccy = mytable.ccy
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 2021-03-14
      • 1970-01-01
      • 2014-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多