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

Query for item with subset of related items

我有两个表:

Part (Table)  
----  
PartID
SerialNumber
CreationDate

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

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

我想要做的是return一个零件列表,其中仅包含对该零件执行的最后一次测试的信息。

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

我想return最后的测试数据和零件的信息:

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

我目前可以得到零件最后一次测试的TestDateTime,但是这个查询没有其他信息(因为子查询不能return more item):

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

我可以采用其他方法来获取我正在寻找的数据吗?

尝试在联接中使用子查询,然后基于它进行过滤。您的子查询应该 select PardID 和 Max(TestDateTime)

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

然后只需加入此 table

即可过滤您的主要查询
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 个条目。如果包含时间,则两个确切的日期时间极不可能匹配任何一个部分的两个不同测试。

这是另一种方法,它只命中测试 table 一次。

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