SQL根据第一个表的ID(Key)从两个表中检索数据

时间:2012-02-23 00:58:41

标签: sql sql-server-2008

我想这已经很久以前已经完成但是我不能为我的生活弄明白而且我已经厌倦了尝试工作。

我有两张桌子 一个是具有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

3 个答案:

答案 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