2012-11-13 32 views
0

我有以下表格,它代表項目的估值。如何檢索對應於SQL中其他列中的最大值的值?

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的教程,我最終設法希望SQL服務器會理解的

SELECT A.ITEM, A.VALUATION, MAX(A.REFERENCEDATE) 
FROM VALUATIONS A 
GROUP BY A.ITEM 

全部我需要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的估值?

注:我需要工作至少在甲骨文的解決方案和SQL Server

編輯:謝謝大家的幫助。我被困在一個洞中,試圖逃脫只有一個SELECT ... GROUP BY請求。現在我看到有一些闡明圍繞着同樣的想法兩種方法:

  1. 製作與其他獨立的請求的結果,將返回所有的項目/ MAX(日期)夫婦
  2. 使用子請求結果的JOIN在where子句中,每個item都會有不同的值。

有人可以提供一個理由(或指向一個理由)更喜歡一個到另一個?

+0

關於你的問題哪個解決方案更好:你將不得不比較每個解決方案的執行計劃。它在很大程度上取決於查詢優化器,定義的索引和涉及的數據。 –

回答

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 
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)列中的最大值。如果您只希望一列具有最大值,那麼只需從它可以選擇的列中進行選擇即可。

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 
         ) 

SQL Fiddle version

在回答您的編輯,只有這樣,才能確切知道哪種方法更好的表現是評估其對每個查詢的執行計劃。確定最快方法的因素有很多,當然DBMS本身就是其中一個因素。一個好的查詢引擎應該能夠推導出相同或相似的執行計劃,而不管這種方法如何。也就是說,使用派生表(即方法#1)可能對查詢引擎更加明確(即使對查詢的讀者不那麼明確)並且因此可能表現更好。派生表通常比相關子查詢(我的解決方案和您的方法#2)執行得更好。但是,除非我有證據支持這一變化,否則我不會改變方法。再一次,要知道哪些方法可以更好地執行某些功能的唯一方法是根據您的數據評估執行計劃。

+0

感謝您的回答,它的工作原理。你能否看到我的編輯和幫助指出我們有兩個更好的選擇之一的原因。 –

+0

@SamuelRossille - 完成。然而,Gordon Linoff的方法代表了第三種方法,即使用排名功能。 – Thomas

-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"與表本身是指具有同一項目最大值記錄。

+0

我沒有downvote。只是可能「SELECT *」被認爲是不好的做法,因爲如果將列添加到表中,結果是不穩定的。除此之外,沒有看到任何明顯的失望原因。只是不要個人承擔...這只是一個問答網站。 –

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>) 

行號分配序列2-14的記錄每一個項目。它從1開始爲最大參考日期,然後2爲下一個最大參考日期等等(基於order by子句)。你需要第一個,其中seqnum = 1。

相關問題