我有一张表格,其中包含:
- 金融工具的ID
- 价格
- 记录价格的日期
- 记录价格的实际时间
- 价格来源
我想获得每种工具的索引ID,最新价格,价格来源和最新价格的日期,其中来源为“L”或“R”。我更喜欢源“L”到“R”,但最新的价格更重要(所以如果最新的价格日期只有一个“R”的来源 - 拿这个,但如果最新的日期我们都有,请采取“L” “)。
这是我的SQL:
SELECT tab1.IndexID, tab1.QuoteDate, tab2.Source, tab2.ActualTime FROM
(SELECT IndexID, Max(QuoteDate) as QuoteDate FROM PricesTable GROUP BY IndexID) tab1
JOIN
(SELECT IndexID, Min(Source) AS Source, Max(UpdatedTime) AS ActualTime, QuoteDate FROM PricesTable WHERE Source IN ('L','R') GROUP BY IndexID, QuoteDate) tab2
ON tab1.IndexID = tab2.IndexID AND tab1.QuoteDate = tab2.QuoteDate
但是,我还想提取价格字段,但由于GROUP BY子句而无法获取。我不能在不包括GROUP BY或聚合函数的价格的情况下提取价格。
相反,我不得不将上面的SQL代码加入到另一个SQL中,它只获取索引ID的价格和索引ID并加入。
是否有更快的方式来执行此查询?
编辑:感谢迄今为止的回复。是否有可能就性能方面的哪些方面提供更有效的建议?由于
答案 0 :(得分:4)
在子查询或CTE中使用ROW_NUMBER
来排序您对它们感兴趣的行,然后只选择位于该排序顶部的行。 (使用PARITION
以便为每个IndexId
从1开始重新分配行号:
;WITH OrderedValues as (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY IndexID ORDER BY QuoteDate desc,Source asc) as rn
FROM
PricesTable
)
SELECT * from OrderedValues where rn=1
答案 1 :(得分:3)
尝试:
select * from
(select p.*,
row_number() over (partition by IndexID
order by QuoteDate desc, Source) rn
from PricesTable p
where Source IN ('L','R')
) sq
where rn = 1
(此语法应该适用于相对较新版本的Oracle,SQLServer或PostgreSQL,但在MySQL中不起作用。)