2011-04-19 59 views
2

在表A(別名ai)中,我有一個項目列表。在表B(別名aib)中,我有表A的所有項目的價格歷史記錄,但不是所有項目,對於那些我需要SELECT NULL。我需要從表A中選擇項目,它是表B的最大價格或NULL。SQL Help Requested:SELECT Table A加入表B(最大或無)

下面是我的,但它不工作,如果表B有廣泛的價格歷史記錄,我得到重複的記錄。

這裏的不完全工作查詢:

SELECT * 

FROM ItemGroup aig 

INNER JOIN Item ai ON ai.groupID = aig.ID 

LEFT JOIN Item_Prices aib ON ai.ID = aib.ItemID 

WHERE aig.ID = @groupID AND 
(aib.max_price = (SELECT MAX(price) AS highprice FROM Item_Prices 
    WHERE ItemID = ai.ID) 
    OR aib.price IS NULL) 

ORDER BY end_date 

所有建議都歡迎。

尊敬,

+0

您使用的是什麼RDBMS? – 2011-04-19 21:12:25

+0

這裏還有一張桌子C嗎? – clamchoda 2011-04-19 21:42:58

+0

對不起,遺漏了一些重要的事實:SQL Server 2008 R2和是的,有一個表C. – 2011-04-20 00:45:27

回答

1

@squillman幾乎已經釘上了它。優化:

SELECT GroupID  = aig.groupID  , 
     ItemID  = ai.ID as ItemID , 
     HighestPrice = aib.HighestPrice 
FROM  Item  ai 
left join (select ItemID , 
        HighestPrice = max(price) 
      from Item_Prices 
      group by ItemID 
     ) aib on aib.ItemID = ai.ID 
WHERE ai.groupID = @groupID 
ORDER BY end_date 

如果你正在尋找從表中的ItemGroup是組ID ......你並不需要的表格:你已經獲得組ID在項目表中,這樣的ItemGroup是不必要的,但如果您需要ItemGroup的其他屬性,則需要保留它。將ItemGroup保留爲不應該太多地影響查詢計劃:您最多隻需要一個組,並且大概ItemGroup具有groupID上的覆蓋索引。

distinct對子查詢是不必要的:group by ItemID使子查詢結果集由ItemID唯一。這對性能有影響:distinct表示引擎必須確保結果集是唯一的。有希望的是,優化器會意識到group by使得這個集合是唯一的並且丟棄了distinct,但我不會指望它。

+0

對SQL Server 2008 R2做了一些調整,效果很好。謝謝大家的熱烈支持! – 2011-04-20 00:46:43

1
SELECT * 
FROM ItemGroup aig 
INNER JOIN Item ai ON ai.groupID = aig.ID 
LEFT OUTER JOIN (
    SELECT 
     ItemID,MAX(max_price) 
    FROM Item_Prices 
    GROUP BY ItemID 
) aib ON ai.ID=aib.ItemID 
WHERE aig.ID = @groupID 
ORDER BY end_date 

子查詢的條目標識得到您的最高價格,因此應該過濾掉重複的。

+1

在子查詢中不需要'distinct'。 'Group by ItemID'通過itemID使子查詢結果不同。 – 2011-04-19 23:02:14

+0

@Niholas真正的數據...拿出來了。 – squillman 2011-04-20 00:39:44

0
Select ... 
From ItemGroup As AIG 
    Join Item As AI 
     On AI.ID = AIG.ID 
Where AIG.Id = @groupId 
    And Exists (
       Select 1 
       From Item_Prices As IP1 
        Join (
          Select IP2.ItemID, Max(IP2.Price) As Price 
          From Item_Prices As IP2 
          Group By IP2.ItemId 
          ) As MaxPrices 
         On MaxPrices.ItemID = IP1.ItemID 
          And MaxPrices.Price = IP2.Price 
       Where IP1.ItemID = AI.ID 
       Union All 
       Select 1 
       From Item_Prices As IP1 
       Where IP1.ItemID = AI.ID 
        And IP1.Price Is Null 
       ) 
Order By End_Date 
1

雷,你只是使用項目表將兩個表連接在一起?如果您在查詢的其餘部分不需要項目表中的其他內容,那麼它並不是真的有必要。

如果全部您真正想要做的是「從表A中選擇項目,它是表格B的最大價格或NULL。」如果Item_Prices.price允許爲null,它可以像這樣簡單。

SELECT a.ItemName, MAX(b.price) AS 'MaxPrice' 
FROM Item AS a INNER JOIN Item_Prices AS b 
ON a.groupID = b.ItemID 
GROUP BY a.ItemName 

這是什麼在我的Item_Prices表

Contents of Item_Prices listing several null and duplicate values

這裏是什麼在我的項目表

Contents of Item

結果查詢:

Output from query

這是我的Item表的設計視圖,groupID是主鍵。

Design view of Item table with groupID as primary key

這裏是我的Item_Prices表的設計視圖中,可以設置項目ID爲外鍵

Design view of Item_Prices with itemID as primary key

如果你想選擇你不需要單獨的表數據第三張表格將它們連接起來以備你或任何事物。只要它們在表A(主鍵)中有某種類型的唯一標識符並且表B中的匹配鍵(通常是外鍵)連接起來,你就是金!

如果你確實打算在那裏獲得第三個表格,那麼不要理會!我只是想掀起一個簡單的例子來告訴你,因爲當我在工作/學校時,我看到很多人使用第三張桌子將表連接在一起,這在大多數情況下是毫無意義的!

+0

感謝您的加倍努力。對不起,有一張桌子C. – 2011-04-20 00:47:33

+0

不是一個問題,我想爲那些描述惡劣習慣的人解決問題:P – clamchoda 2011-04-20 01:04:04

+0

你''由'groupID'鍵入,這是一個鍵,但是你'GROUP BY ItemName'這不是關鍵並且是可空的:這是否真的是你想要的,即將具有不同「主標識符」但具有相同(可能是NULL)名稱的項目分組?在我看來,你會得到更可靠的結果給'GROUP BY groupID',即密鑰。 – onedaywhen 2011-04-20 08:44:15