MS SQL Server 2005中有一个货币汇率表:
ID | CURR |率| DATE
1 | USD | 30 | 01.10.2010
3 | GBP | 45 | 2010年7月10日
5 | USD | 31 | 2010年8月10日
7 | GBP | 46 | 2010年9月10日
9 | USD | 32 | 2010.12.10
11 | GBP | 48 |二○一○年三月一十日
费率实时更新,表格中有超过10亿行。
它需要编写一个SQL查询,它将提供每种货币的最新费率。 我的决定是:
SELECT c.[id],c.[curr],c.[rate],c.[date]
FROM [curr_rate] c, (SELECT curr, MAX(date) AS rate_date FROM [curr_rate]
GROUP BY curr) t
WHERE c.date = t.rate_date AND c.curr = t.curr
ORDER BY c.[curr] ASC
是否可以编写没有子查询的查询并使用派生表连接?
答案 0 :(得分:1)
不,我想不是。你有CURR索引和日期吗?
答案 1 :(得分:1)
在调优此查询时,排序索引可能比SQL语法更重要。
将子查询方法与CTE进行比较可能是值得的:
;WITH currCTE
AS
(
SELECT id
,curr
,rate
,date
,ROW_NUMBER() OVER (PARTITION BY curr
ORDER BY date desc
) AS rn
FROM [curr_rate]
)
SELECT id
,curr
,rate
,date
FROM currCTE
WHERE rn = 1
如果表PK在id
上,并且行总是按日期顺序添加到表中,则可以通过在排名的id
子句中使用ORDER BY
来获得更好的性能功能而非日期。
答案 2 :(得分:1)
您的查询不使用子查询,因此无需更改。子查询是一个SELECT查询,它返回单个值并嵌套在SELECT,INSERT,UPDATE或DELETE语句中,或嵌套在另一个子查询中。子查询可以在允许表达式的任何地方使用。见Subquery Fundamentals
您的查询使用的是派生表,也称为内联视图,您将其命名为“t”。
我首先要摆脱古老的连接语法:
SELECT
c.[id],c.[curr],c.[rate],c.[date]
FROM [curr_rate] c
INNER JOIN (SELECT
curr, MAX(date) AS rate_date
FROM [curr_rate]
GROUP BY curr
) t ON c.curr = t.curr AND c.date = t.rate_date
ORDER BY c.[curr] ASC
但它将具有相同的执行计划。您可以将派生表移动到CTE中,但这与派生表大致相同。
如果您在以下位置创建索引视图,查询可能会运行得更快:
SELECT
curr, MAX(date) AS rate_date
FROM [curr_rate]
GROUP BY curr
带有curr + MAX(日期)的索引。如果你在[curr_rate] .curr + date上有一个索引,你的查询会有更好的表现并且是:
SELECT
c.[id],c.[curr],c.[rate],c.[date]
FROM [curr_rate] c
INNER JOIN [curr_rate_max_view] t ON c.curr = t.curr AND c.date = t.rate_date
ORDER BY c.[curr] ASC
答案 3 :(得分:0)
我不知道你可以避免使用子选择,但你可以避免加入甚至是group by
:
SELECT id, curr, rate, date
FROM curr_rate r
WHERE date = (
SELECT MAX(date)
FROM curr_rate
WHERE curr = r.curr
)
ORDER BY curr ASC
我不知道这将如何表现。