查询具有相关项子集的项目

时间:2015-01-13 21:22:25

标签: sql-server tsql join subquery

我有两张桌子:

Part (Table)  
----  
PartID
SerialNumber
CreationDate

Test (Table)
----
PartID
TestName
TestDateTime
TestResult

这些表在PartID上有一对多关系,一部分可能有多个Test条目。

我要做的是返回一个部件列表,其中只包含该部件上最后一次测试的信息。

Part                                 Test
PartID  SerialNumber CreationDate    PartID TestName TestDateTime TestResult
--------------------------------     -------------------------------------------
1       555          12/9/2013       1      Test 1   1/1/2014     Pass
                                     1      Test 2   2/2/2014     Fail

我想用零件的信息返回最后的测试数据:

PartID SerialNumber CreationDate TestName TestDateTime TestResult
-----------------------------------------------------------------
1      555          12/9/2013    Test 2   2/2/2014     Fail

我目前可以获得该部分最后一次测试的TestDateTime,但此查询没有其他信息(因为子查询不能返回更多项目):

SELECT PartID, SerialNumber, CreationDate,
       (SELECT        TOP (1) TestDateTime
        FROM            Test
        WHERE        (PartID = Part.PartID)
        ORDER BY TestDateTime DESC) AS LastDateTime
FROM            Part
ORDER BY SerialNumber

我可以采取不同的方法来获取我正在寻找的数据吗?

2 个答案:

答案 0 :(得分:2)

这是另一种方法,只能击中Test表一次。

with SortedData as
(
    SELECT PartID
        , SerialNumber
        , CreationDate
        , TestDateTime
        , ROW_NUMBER() over (Partition by PartID ORDER BY TestDateTime DESC) AS RowNum
    FROM Part p
    join Test t on t.PartID = p.PartID
)

select PartID
    , SerialNumber
    , CreationDate
    , TestDateTime
from SortedData
where RowNum = 1
ORDER BY SerialNumber

如果您在2012年或之后,您还可以使用FIRST_VALUE

答案 1 :(得分:0)

尝试在联接中使用子查询,然后根据该查询进行过滤。您的Sub查询应选择PardID和Max(TestDateTime)

Select TestSubQ.PartID, Max(TestSubQ.TestDateTime)
From Test TestSubQ
group by TestSubQ.PartID

然后只需加入此表

过滤您的主要查询
Select Part.PartID, SerialNumber, CreationDate,
       TestMain.PartID, TestMain.TestName, TestMain.TestDateTime, TestMain.TestResult
From Part
    Left Outer Join (Select TestSubQ.PartID, Max(TestSubQ.TestDateTime)
                     From Test TestSubQ
                     group by TestSubQ.PartID) TestPartSub
        On Part.PartID = TestPartSub.PartID
    Left Outer Join Test TestMain
        On TestPartSub.PartID = TestMain.PartID
           And TestPartSub.TestDateTime = TestMain.TestDateTime
Order By SerialNumber

请注意,如果您的数据仅包含日期而非时间,那么如果在同一日期进行了两次测试,您仍可能最终得到2个条目。如果包含时间,则两个确切的日期时间极不可能匹配任何一个部分的两个不同的测试。