我想这以前已经做过很多次了,但我无论如何也想不出来,我厌倦了尝试变通的方法。
我有两张桌子。
一个是具有ObjectID (关键字)、名称、类型、位置的对象,第二个是具有StatusID(关键字)、ObjectID、Status、DateChanged、UserWhoChangedStatus的ObjectStatus
我想要做的是返回所有对象和最后输入的ObjectStatus
表1对象
ObjectID Name Type Location
1 Blue Ball Ball ToyBox
2 Red Ball Ball ToyBox表2 (ObjectStatus)
StatusID ObjectID Status DateChanged UserWhoChangedStatus
1 2 Broken 2012-01-25 56481
2 2 Fixed 2012-01-30 98526
3 1 Bouncy 2012-01-05 85245
4 1 Sticky 2012-02-10 56481我会想要得到回报
ObjectID Name Type Location StatusID Status DateChanged UserWhoChangedStatus
1 Blue Ball Ball ToyBox 4 Sticky 2012-02-10 56481
2 RedBall Ball ToyBox 2 Fixed 2012-01-30 98526,它是所有对象和最后输入的ObjectStatus
发布于 2012-02-23 09:16:30
既然你没有提到DBMS,我就假定是Ms Sql Server。
SELECT
O.*,
S.*
FROM
dbo.Object O
OUTER APPLY (
SELECT TOP 1 *
FROM dbo.ObjectStatus S
WHERE O.ObjectID = S.ObjectID
ORDER BY DateChanged DESC
) S发布于 2012-02-23 09:43:13
只是为了提供另一种解决方案,以便将来的读者可以比较性能,并根据自己的情况选择合适的方法。
;WITH LastChange AS
(
SELECT
ObjectID, Status, DateChanged, UserWhoChangedStatus,
rn = ROW_NUMBER() OVER (PARTITION BY ObjectID ORDER BY DateChanged DESC)
FROM dbo.ObjectStatus
)
SELECT
o.ObjectID, o.Name, o.Type, o.Location,
l.StatusID, l.Status, l.DateChanged, l.UserWhoChangedStatus
FROM dbo.Object AS o
LEFT OUTER JOIN LastChange AS l
ON o.ObjectID = l.ObjectID
AND l.rn = 1;如果您以某种方式知道状态表对于每个ObjectID总是至少有一行,或者如果您不想返回状态中没有行的对象,则可以将LEFT OUTER JOIN更改为INNER JOIN。
发布于 2012-02-23 09:44:53
有很多方法可以做到这一点,但我喜欢下面的方法,因为它看起来最直观--它使用了CTE和左连接,如果查询变得更复杂,它会变得更简单:
WITH maxDate AS
(
SELECT objectID, MAX(DateChanged) AS maxDate
FROM ObjectStatus
GROUP BY objectID
)
SELECT O.*, OS.*
FROM Object O
LEFT JOIN maxDate ON maxDate.objectID = O.ObjectID
LEFT JOIN ObjectStatus ON OS.ObjectID = O.ObjectID
AND OS.DateChanged = maxDate.maxDatehttps://stackoverflow.com/questions/9405627
复制相似问题