2012-04-24 64 views
1

我有一个简单的项目表。称他们为“零件”。简单表加入访问加入表列

每个零件在一个单独的表中可以有零个或多个相关条目,称它们为“SubParts”。 表的一个简单的观点是,你可能会想到:

Parts 
----- 
PartID int (PK) 
PartName varchar 

SubParts 
-------- 
SubPartID int (PK) 
PartID int (FK_Parts) 
SubPartName varchar 
SubPartAdded datetime 

我想,如果从主表中返回的所有部分,但也有(由SubPartAdded降序排列)获得最新的相关分部它存在。

我的困惑是,在子部件表(对于许多不同的部件)中有1M +条目,并且我只需要当前部件的最新条目(如果存在)。

早些时候,我写了一个进行左部件表和相关的子部分派生表(工作)之间的连接,但派生表似乎返回的子部分表中的所有行造成的性能损失的声明。我基本上需要在派生select语句中执行TOP 1和DESC命令,以便通过PartID(以及其他一些列)预过滤子部分。然而,因为我似乎不能引用派生选择语句中的部分表(外部)列,所以我不能在派生表中添加WHERE子句。

我也曾尝试下面的代码片段这确实执行,但犯规返回任何相关记录:

SELECT p.PartName, sp.SubPartName, sp.SubPartAdded 
    FROM Parts p 
    LEFT JOIN (SELECT TOP 1 SubPartID, SubpartAdded, PartID FROM SubParts ORDER BY SubPartAdded) AS sp 
       ON sp.PartID = p.PartID 

我想象中的“TOP 1”语句执行对整个子部分表,由被过滤前“ON”声明(?)

最终我需要使用子部件表中的一些列,但不包括主存储过程,所以我不想仅仅需要相关的子查询,因为这需要多次调用。

我希望这是很清楚的(这PROC会返回在每次执行多个部分。即在PROC不会被单一PARTID过滤)? 听起来它应该有一个非常简单的解决方案,但我目前很难过! (与SQL Server 2K以上兼容性是必需的)

问候 尼克

回答

1

下应该努力回到SQL Server 2000中

SELECT PartName, SubPartName, SubPartAdded 
FROM Parts 
     LEFT JOIN 
     ( SELECT SubParts.PartID, SubParts.SubPartName SubParts.SubPartAdded 
      FROM SubParts 
        INNER JOIN 
        ( SELECT PartID, MAX(SubPartAdded) [SubPartAdded] 
         FROM SubParts 
         GROUP BY PartID 
        ) MaxSubPart 
         ON MaxSubPart.PartID = SubParts.PartID 
         AND MaxSubPart.SubPartAdded = SubParts.SubPartAdded 
     ) Subpart 
      ON SubPart.PartID = Parts.PartID 

在更高版本(OUTER APPLY或Window函数)中有更高效和更高效的方法来执行此操作,但我不确定有多少种方法向后兼容SQL Server 2000

+0

非常感谢Gareth。 – 2012-04-24 12:11:56

0

您需要派生表抽取最后的子部分。然后,您可以过滤子部分通过ID其连接到派生表和SubPartAdded列:

SELECT p.PartName, sp.SubPartName, sp.SubPartAdded 
FROM Parts p 
LEFT JOIN SubParts sp 
    ON p.PartID = sp.PartID 
LEFT JOIN 
(
    SELECT PartID, max (SubPartAdded) MaxSubPartAdded 
    FROM SubParts 
    GROUP BY PartID 
) AS MaxSP 
    ON sp.PartID = MaxSP.PartID 
AND sp.SubPartAdded = MaxSP.MaxSubPartAdded 

如果SQL Server 2005或更新:

SELECT p.PartName, sp.SubPartName, sp.SubPartAdded 
FROM Parts p 
OUTER APPLY 
(
    select top 1 
      SubPartName, SubPartAdded 
    from SubParts 
    where SubParts.PartID = p.PartID 
    order by SubPartAdded desc 
) sp 
+0

您的第一个查询需要MaxSP子查询中的“GROUP BY”,而不是“ORDER BY”。即使有这个修正,尽管它会返回所有的子部分。你需要一个where子句来声明'WHERE MaxSp。PartID不为空或sp.PartID为NULL',这将删除不是最新的子部分,同时仍允许没有子部分的子部分。 – GarethD 2012-04-24 10:19:13

+0

@GarethD我搞砸了编辑。它应该用连接子句表示。 – 2012-04-24 10:22:18