2010-06-09 70 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行恰好指向同一行,但这肯定不会通过您拥有的模式实施。

相关问题