2011-11-30 92 views
0

我不知道,標題是非常描述性的,但這裏的問題,選擇一個基於MAX(關鍵)數據...如何不進行分組

有沒有一種方法來選擇基於數據列Max鍵值,跨多個表連接。請考慮:

Table A 
------- 
PK1 
PK2 
PK3 
PK4 
dataColumn 
... data 

Table B 
------- 
PK1 
PK2 
PK3 
... data 

Table C 
------- 
PK1 
PK2 
PK3 
PK4 
... data 

SELECT A.dataColumn, A.PK1, A.PK2, MAX(A.PK3), A.PK4 
FROM A a INNER JOIN B b ON a.PK1 = b.PK1 AND a.PK2 = b.PK2 AND a.PK3 = b.PK3 
     INNER JOIN C c ON a.PK1 = c.PK1 AND a.PK2 = c.PK2 AND a.PK3 = c.PK3 AND a.PK4 = c.PK4 
GROUP BY A.PK1, A.PK2, A.PK4 -- I do not want to add in A.dataColumn 

的問題是,爲了得到MAX(A.PK3),我也必須由數據,這組我不想要的。 A.PK1,A.PK2,A.PK4和MAX(A.PK3)唯一地定義了我想要的行。通過在組中添加,我將得到每個A.dataColumn的MAX(A.PK3),這不是我想要的。基本上,A.PK3是一個日期時間字段;我想要基於其他鍵的最新時間的數據。其他鍵唯一標識一些設備,時間是錯誤的時間,然後數據是錯誤信息(非常簡化)。我想要指定PK1,PK2和PK4的最新錯誤信息。

目前,我們分成兩個,幾乎相同的查詢,並加入他們的行列爲:

SELECT j.PK1, j.PK2, j.PK3, j.PK4, k.dataColumn 
FROM A a 
INNER JOIN 
(
    SELECT A.PK1, A.PK2, MAX(A.PK3), A.PK4 -- no data column selected 
    FROM A a INNER JOIN B b ON a.PK1 = b.PK1 AND a.PK2 = b.PK2 AND a.PK3 = b.PK3 
      INNER JOIN C c ON a.PK1 = c.PK1 AND a.PK2 = c.PK2 AND a.PK3 = c.PK3 AND a.PK4 = c.PK4 
    GROUP BY A.PK1, A.PK2, A.PK4 
) j 
ON a.PK1 = j.PK1 AND a.PK2 = j.PK2 AND a.PK3 = j.PK3 AND a.PK4 = j.PK4 
INNER JOIN 
(
    SELECT A.dataColumn, A.PK1, A.PK2, A.PK3, A.PK4 -- data column, but no MAX 
    FROM A a INNER JOIN B b ON a.PK1 = b.PK1 AND a.PK2 = b.PK2 AND a.PK3 = b.PK3 
      INNER JOIN C c ON a.PK1 = c.PK1 AND a.PK2 = c.PK2 AND a.PK3 = c.PK3 AND a.PK4 = c.PK4 
) k 
ON j.PK1 = k.PK1 AND j.PK2 = k.PK2 AND j.PK3 = k.PK3 AND j.PK4 = k.PK4 

所以,你可以看到,第一INNER JOIN得到的PK,而不是數據,那麼第二個連接從第一個內部聯接中的PK獲取數據。這似乎是可怕的!這個例子過於簡化,但在我們的例子中,我們加入的表包含數百萬條記錄,並且每個JOIN中的操作幾乎相同。

任何幫助刪除內部聯接之一將是真棒和讚賞!

回答

3

一個選項,在SQL 2005和起來,就是用的「排行榜」功能中的一個,像這樣:

SELECT SubQuery.dataColumn, SubQuery.PK1, SubQuery.PK2, SubQuery.A.PK3, SubQuery.PK4 
FROM (SELECT A.dataColumn, A.PK1, A.PK2, A.PK3, A.PK4 
     ,row_number() over (partition by A.PK1, A.PK2, A.PK4 order by A.PK3 desc) Ranking 
     FROM A a INNER JOIN B b ON a.PK1 = b.PK1 AND a.PK2 = b.PK2 AND a.PK3 = b.PK3 
       INNER JOIN C c ON a.PK1 = c.PK1 AND a.PK2 = c.PK2 AND a.PK3 = c.PK3 AND a.PK4 = c.PK4 
     GROUP BY A.PK1, A.PK2, A.PK4) SubQuery 
WHERE SubQuery.Ranking = 1 

最佳詳細解釋books online。注意事項:我無法測試上述代碼,可能存在拼寫錯誤或小錯誤。而且,雖然邏輯上合理,但性能可能不佳,因此需要測試性能是否足夠。

+0

太棒了,謝謝。我將對此進行測試,併發布如何執行這一操作,而不是按照指示分割查詢。 – MPavlak