我想这已经很久以前已经完成但是我不能为我的生活弄明白而且我已经厌倦了尝试工作。
我有两张桌子 一个是具有ObjectID(密钥),名称,类型,位置的对象 两个是ObjectStatus,具有StatusID(key),ObjectID,Status,DateChanged,UserWhoChangedStatus
我想要做的是返回所有对象和最后输入的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
答案 0 :(得分:3)
由于您没有说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
答案 1 :(得分:1)
只是提供一个替代解决方案,以便未来的读者可以比较性能并选择适当的方法。
;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;
如果您知道状态表每个LEFT OUTER JOIN
始终至少有一行,或者您不想返回,则可以将INNER JOIN
更改为ObjectID
状态中没有行的对象。
答案 2 :(得分:0)
有很多方法可以做到这一点,但我喜欢以下方式,因为它看起来最直观 - 它使用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.maxDate