SQL извлекает данные из двух таблиц на основе идентификатора (ключа) первой таблицы - PullRequest
3 голосов
/ 23 февраля 2012

Я полагаю, что это было сделано много раз, но я не могу понять, и я устала пробовать обходные пути.

У меня есть два стола.
ОдинObject, имеющий ObjectID (ключ), Name, Type, Location Two - это ObjectStatus, имеющий StatusID (ключ), ObjectID, Status, DateChanged, UserWhoChangedStatus

Что я хочу сделать, это вернуть все объекты и ObjectStatus, которые были введеныlast

Таблица 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 ]

3 голосов
/ 23 февраля 2012

Поскольку вы не сказали СУБД, я приму 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 голос
/ 23 февраля 2012

Просто чтобы предложить альтернативное решение, чтобы будущие читатели могли сравнить производительность и выбрать подходящий метод в своем случае.

;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, или если вы не хотите возвращать объекты, которые не имеют строка в статусе.

0 голосов
/ 23 февраля 2012

Есть несколько способов сделать это, но мне нравится следующий способ, потому что он кажется наиболее интуитивно понятным - он использует CTE и левые соединения, что делает его проще, если запрос становится более сложным:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...