我有下表,表示项目的估值。
ITEM REFERENCEDATE VALUATION
------------------------------------------------
A 25/01/2012 25.35
A 26/01/2012 51.35
B 25/01/2012 25.00
编辑:(ITEM,REFERENCEDATE)是一个独特的索引。
目标是获取一组项目的最新估值。这意味着我正在尝试创建一个返回类似
的SQL请求ITEM REFERENCEDATE VALUATION
------------------------------------------------
A 26/01/2012 51.35
B 25/01/2012 25.00
在GROUP BY上发布教程,我最终尝试了
SELECT A.ITEM, A.VALUATION, MAX(A.REFERENCEDATE)
FROM VALUATIONS A
GROUP BY A.ITEM
完全希望SQL服务器能够理解我需要A.VALUATION来实现当前结果行上表示的ITEM的A.REFERENCEDATE的最大值。
但相反,我有这个令人不快的错误信息:
Column 'VALUATIONS.VALUATION' is invalid in the select list because it is not contained
in either an aggregate function or the GROUP BY clause.
我如何指出应该使用最大REFERENCEDATE的VALUATION?
注意:我需要一个至少在Oracle和SQL Server上运行的解决方案
编辑:感谢大家的帮助。我被困在一个洞里试图逃脱只有一个SELECT ... GROUP BY请求。现在我看到有两种方法可以围绕同一个想法表达出来:
任何人都可以提供一个理由(或指向一个理由的指针)来优先选择其中一个吗?
答案 0 :(得分:4)
Select V.Item, V.ReferenceDate, V.Valuation
From Valuations As V
Where V.ReferenceDate = (
Select Max(V1.ReferenceDate)
From Valuations As V1
Where V1.Item = V.Item
)
为了响应您的编辑,确定哪种方法将更好地执行的唯一方法是评估每个查询的执行计划。决定最快方法的因素有很多,当然DBMS本身就是其中一个因素。无论采用何种方法,良好的查询引擎都应该能够推导出相同或类似的执行计划。也就是说,使用派生表(即方法#1)可能对查询引擎更加明确(即使对查询的读者不太明确),因此可能表现得更好。通常情况下,派生表的性能优于相关子查询(我的解决方案和方法#2)。但是,在我有证据支持这一改变之前,我不会改变方法。同样,了解哪些会更好地执行某些操作的唯一方法是根据您的数据评估执行计划。
答案 1 :(得分:3)
如果您使用的是几乎所有MySQL以外的数据库,那么答案就是使用排名功能。特别是,row_number
可以满足您的需求:
select ITEM, REFERENCEDATE, VALUATION
from (select t.*
row_number() over (partition by item order by referencedate desc) as seqnum
from t
) t
where seqnum = 1 and
item in (<your list of items>)
行号将序列nubmer分配给每个项目的记录。它从最大参考日期的1开始,然后是下一个最大的2,依此类推(基于order by子句)。你想要第一个,其中seqnum = 1。
答案 2 :(得分:2)
select a.item, a.valuation, a.referencedate
from valuations a
join (select a2.item, max(referencedate) as max_date
from valuations a2
group by a2.item
) b ON a.item = b.item and a.referencedate = b.max_date
答案 3 :(得分:1)
试试这个:
SELECT A.ITEM, MAX(A.VALUATION), A.REFERENCEDATE
FROM VALUATIONS A
JOIN
(
SELECT A.ITEM, MAX(A.REFERENCEDATE) AS REFERENCEDATE
FROM VALUATIONS A
GROUP BY A.ITEM
) B ON A.ITEM = B.ITEM AND A.REFERENCEDATE = B.REFERENCEDATE
GROUP BY A.ITEM, A.REFERENCEDATE
它将从保持最大值(REFERENCEDATE)的列中选择MAX值。如果您只希望一列具有最大值,则只需从它可以选择的列中进行选择。
答案 4 :(得分:-1)
这是您可能需要的代码:
Select *
From ItemValues As A
Inner Join
ItemValues As MaxValuedItem
On MaxValuedItem.Id = (
Select Top 1
B.Id
From ItemValues As B
Where B.Item_Id = A.Item_Id
Order By B.Valuation Desc
)
您需要使用表格本身的"join"
,该表格指的是相同项目最大值的记录强>