【问题标题】:Oracle: get the closest date for each id efficientlyOracle:有效地获取每个 id 的最近日期
【发布时间】:2011-08-24 21:05:12
【问题描述】:

我正在尝试创建一个查询,该查询返回表 price 中表 date 中每个日期的每个 ID 的最接近(高于)价格。

date 中有这些日期:

date
2010-11-25
2010-11-24
2010-11-10

price如下:

id  date        price
A   2010-11-26  24.99
A   2010-11-24  27.99
A   2010-11-13  22.12
B   2010-11-26  26.51
B   2010-11-24  23.24
B   2010-11-22  27.95

所以对于2010-11-25,我应该得到

id  date        price
A   2010-11-26  24.99
B   2010-11-26  26.51

2010-11-10

id  date        price
A   2010-11-13  22.12
B   2010-11-22  27.95

2010-11-24

id  date        price
A   2010-11-24  27.99
B   2010-11-24  23.24

等等

我相信获得给定日期的结果是可行的(也许通过...进行分组),但是我正在寻找一种可以在所有日期都完成的解决方案。

编辑:

示例中有错误,已更正...

【问题讨论】:

  • 我真的看不出那些'B'记录中的逻辑。为什么要为“2010-10-25”获得“2010-11-26”?
  • @Golez 因为那是 id B 最接近的日期(我猜这里)
  • 我想是的,如果我读了解释,但 2010-11-22 似乎更接近我。
  • @Golez 确实。这可能只是一个错误。
  • 我想是的。我的回答是基于这个假设。 :)

标签: sql oracle


【解决方案1】:

我认为您的意思是,但您的示例中可能存在错误。 (或误解)。

select
  id, date,price
from
  (select
    p.id,
    p.date,
    p.price,
    dense_rank() over (partition by d.date, p.id order by p.date) as rank
  from
    date d
    inner join price p on p.date > d.date)
where
  rank = 1

【讨论】:

  • 我认为您生成的行数超过了应有的行数
  • 我认为这可能是由order by d.date 引起的,应该是order by p.date。修复了这个。虽然我不得不承认我这里没有 Oracle,而且记事本是一个糟糕的查询测试器。 :)
【解决方案2】:

我认为这应该对你有用:

select x.date_1 as candidate_date ,
       t.*
from ( select d."date"        as date_1  ,
              p.id ,
              min( p."date" ) as date_2
        from      "date" d
        left join price  p on p."date" >= d."date"
        group by p.id     ,
                 d."date"
     ) x
left join price t on t.id     = x.id
                 and t."date" = x.date_2
order by 1,2,3

from 子句中的虚拟表应该为价格表中的每个“id”提供 1 行,其日期大于或等于日期表中的候选日期。

【讨论】:

  • 我认为您生成的行数也多于应有的行数
【解决方案3】:
SELECT
    d.date AS searchDate
    p.id
    p.date
    p.price
FROM 
    date d
  ,                              --- this is a CROSS JOIN
    ( SELECT DISTINCT id
      FROM price
    ) product
  JOIN
    price p
      ON  p.id = product.id
      AND p.date =
          ( SELECT MIN(p2.date)
            FROM price AS p2
            WHERE p2.date >= d.date
          )

【讨论】:

  • @NullUserException: 你可以尝试用逗号替换CROSS JOIN,
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-24
  • 2018-04-16
  • 2021-11-04
  • 2019-12-27
  • 2012-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多