假设我有一张包含此类数据的表格:
Parent Value DateFor ValueType
3177 50.110000 2016-03-05 1
3177 254390.000000 2016-03-05 2
3177 50.110000 2016-03-06 1
3177 254390.000000 2016-03-06 2
3294 40.800000 2016-03-05 1
3294 20280.000000 2016-03-05 2
在Parent
列的帮助下,我的表在Id上有一个PRIMARY索引(此处未显示id)和一个与父表的FOREIGN关系。
我想为每个Parent选择值类型的最新值:
3177 50.110000 2016-03-06 1
3177 254390.000000 2016-03-06 2
3294 40.800000 2016-03-05 1
3294 20280.000000 2016-03-05 2
解释:我忽略了2015-03-05对于父3177的两个值,因为它有2016-03-06的数据。但我从2016-03-05获取父母3294的数据,因为这是我最新的数据。
实现此目的的性能最高的查询是什么?因为我的桌子有数百万行...
是否可以避免子查询?
答案 0 :(得分:3)
使用分析函数和覆盖索引可以在牺牲一些磁盘空间的情况下获得良好的性能;
CREATE INDEX ix_test
ON myTable([Parent], [ValueType], [DateFor] DESC) INCLUDE ([Value]);
GO
SELECT [Parent], [Value], [DateFor], [ValueType]
FROM (
SELECT *, ROW_NUMBER()
OVER (PARTITION BY [Parent], [ValueType] ORDER BY [DateFor] DESC) rn
FROM myTable
) z
WHERE rn=1;
答案 1 :(得分:1)
这个问题过于宽泛,因此答案是通用的。使用带有子查询的SQL查询或临时表(后者可能会带来更好的性能)。首先,按SELECT MAX(DateFor) as MinDate FROM [YourTable] Group BY [Parent], [ValueType]
获取最早的日期(最小值),然后在SELECT
子句中使用MinDate
运行第二个WHERE
语句。希望这会有所帮助。
答案 2 :(得分:1)
另一种可能具有良好性能的方法是:
SELECT [Parent], [Value], [DateFor], [ValueType]
FROM t
WHERE DateFor = (SELECT MAX(t2.DateFor)
FROM t t2
WHERE t2.Parent = t.Parent AND t2.ValueType = t.ValueType
);
这需要与Joachim建议的索引相同的索引。在某些情况下,这可能会略微加快。您可以在数据上测试这两个。