查询具有相关项目子集的项目
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
我有两个表:
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