2010-06-09 88 views
2

我有一個問題,最好的方法是返回多對多關係表另一端的相關表中的一段數據。在SQL語句中返回相關數據的最佳方法

我的第一個方法使用連接返回數據,但由於關係表中有多個匹配的行,我不得不使用TOP 1來獲得單行結果。

我的第二種方法使用子查詢來獲取數據,但這只是感覺不對。

所以,我的問題是,哪個是首選方法,還是有更好的方法?

下面是創建測試表,插入數據和運行兩個查詢所需的腳本。

感謝您的諮詢!

Darvis

創建表

DECLARE @TableA TABLE (
[A_ID] [int] IDENTITY(1,1) NOT NULL, 
[Description] [varchar](50) NULL) 

DECLARE @TableB TABLE (
[B_ID] [int] IDENTITY(1,1) NOT NULL, 
[A_ID] [int] NOT NULL, 
[Description] [varchar](50) NOT NULL) 

DECLARE @TableC TABLE (
[C_ID] [int] IDENTITY(1,1) NOT NULL, 
[Description] [varchar](50) NOT NULL) 

DECLARE @TableB_C TABLE (
[B_ID] [int] NOT NULL, 
[C_ID] [int] NOT NULL) 

插入測試數據

INSERT INTO @TableA VALUES('A-One') 
INSERT INTO @TableA VALUES('A-Two') 
INSERT INTO @TableA VALUES('A-Three') 

INSERT INTO @TableB (A_ID, Description) VALUES(1,'B-One') 
INSERT INTO @TableB (A_ID, Description) VALUES(1,'B-Two') 
INSERT INTO @TableB (A_ID, Description) VALUES(1,'B-Three') 
INSERT INTO @TableB (A_ID, Description) VALUES(2,'B-Four') 
INSERT INTO @TableB (A_ID, Description) VALUES(2,'B-Five') 
INSERT INTO @TableB (A_ID, Description) VALUES(3,'B-Six') 

INSERT INTO @TableC VALUES('C-One') 
INSERT INTO @TableC VALUES('C-Two') 
INSERT INTO @TableC VALUES('C-Three') 

INSERT INTO @TableB_C (B_ID, C_ID) VALUES(1, 1) 
INSERT INTO @TableB_C (B_ID, C_ID) VALUES(2, 1) 
INSERT INTO @TableB_C (B_ID, C_ID) VALUES(3, 1) 

獲取結果 - 方法1

SELECT TOP 1 C.*, A.Description 
FROM @TableC C 
JOIN @TableB_C BC ON BC.C_ID = C.C_ID 
JOIN @TableB B ON B.B_ID = BC.B_ID 
JOIN @TableA A ON B.A_ID = A.A_ID 
WHERE C.C_ID = 1 

獲取結果 - 方法2

SELECT C.*,    
(SELECT A.Description 
FROM @TableA A 
WHERE EXISTS (SELECT * 
     FROM @TableB_C BC 
     JOIN @TableB B ON B.B_ID = BC.B_ID 
     WHERE BC.C_ID = C.C_ID AND B.A_ID = A.A_ID)) 
FROM @TableC C 
WHERE C.C_ID = 1 
+0

您應該小心計數IDENTITY列以始終順序上升。這不能保證。 – 2010-06-09 14:16:56

回答

0

你不列出的表格中任何指數或PK信息,所以這是首先要做的優化,如果他們已經沒有那些。

根據有限的測試數據不可能告訴你,優化器將根據你的實際數據使用統計數據來確定索引使用情況和最佳查詢執行計劃。

您可以在SQL Server Management Studio查詢窗口中使用SET SHOWPLAN_ALL ON查看每個查詢的執行計劃,然後比較它們以查看哪個更好。

對於快速檢查嘗試這個:運行SET SHOWPLAN_ALL ON然後方法1查詢,看第TotalSubtreeCost第一行。然後,運行方法2查詢並再次查看第一行的TotalSubtreeCost。哪個查詢的值較低?如果您想進行更詳細的評估,您可以查看StmtText,EstimateIO和EstimateCPU以及任何其他列。

+0

感謝您的回覆。我知道很難說如果不查看這些測試表建模之後的真實表和數據,哪個性能更快。如果其中一種查詢方法引發了紅旗或者有人有更好的方法來執行查詢,我想我會更好奇。從你的迴應來看,這聽起來不像聽起來那麼荒謬。再次感謝。 – DarLom 2010-06-09 14:12:06

0

如果您想在一個表中的某行可能與另一個表中的多行相關的情況下獲取單行,那麼您需要定義要使用哪些行。一旦你有了定義,那麼你可以編寫一個查詢來獲取該行。

就你而言,無論你通過@TableB和@TableB_C通過哪種方式,所有C行恰好指向同一行,但這肯定不會通過您擁有的模式實施。