Учитывая следующие данные в качестве примера:
Users
+--------------------------------------------------+
| ID | First Name | Last Name | Network Identifier |
+--------------------------------------------------+
| 1 | Billy | O'Neal | bro4 |
+----+------------+-----------+--------------------+
| 2 | John | Skeet | jsk1 |
+----+------------+-----------+--------------------+
Hardware
+----+-------------------+---------------+
| ID | Hardware Name | Serial Number |
+----------------------------------------+
| 1 | Latitude E6500 | 5555555 |
+----+-------------------+---------------+
| 2 | Latitude E6200 | 2222222 |
+----+-------------------+---------------+
HardwareAssignments
+---------+-------------+-------------+
| User ID | Hardware ID | Assigned On |
+-------------------------------------+
| 1 | 1 | April 1 |
+---------+-------------+-------------+
| 1 | 2 | April 10 |
+---------+-------------+-------------+
| 2 | 2 | April 1 |
+---------+-------------+-------------+
| 2 | 1 | April 11 |
+---------+-------------+-------------+
Я хотел бы записать SQL-запрос, который даст следующий результат:
+--------------------+------------+-----------+----------------+---------------+-------------+
| Network Identifier | First Name | Last Name | Hardware Name | Serial Number | Assigned On |
+--------------------------------------------------------------------------------------------+
| bro4 | Billy | O'Neal | Latitude E6200 | 2222222 | April 10 |
+--------------------+------------+-----------+----------------+---------------+-------------+
| jsk1 | John | Skeet | Latitude E6500 | 5555555 | April 11 |
+--------------------+------------+-----------+----------------+---------------+-------------+
Моя проблема состоит в том, что максимум, "Присвоенный В" дату каждого пользователя, должен выбираться для каждого отдельного пользователя и использоваться для фактического соединения...
Существует ли умный путь, выполняют это в SQL?
SELECT U.NetworkIdentifier, U.FirstName, U.LastName,
H.HardwareName, H.SerialNumber
FROM (SELECT UserID, MAX(AssignedOn) LastAssignment
FROM HardwareAssignments
GROUP BY UserID) AS T
JOIN HardwareAssignments AS HA
ON HA.UserId = T.UserID AND HA.AssignedOn = T.LastAssignment
JOIN Users AS U ON U.ID = HA.UserID
JOIN Hardware AS H ON H.ID = HA.HardwareID
ORDER BY U.NetworkIdentifier;
Разница между этим и ответом Джастина Нисснера заключается в том, где появляется подзапрос; здесь я создал его в предложении FROM. Это в значительной степени гарантирует, что он будет выполнен один раз. Когда есть коррелированный подзапрос в предложении WHERE, как в ответе Джастина, возможно, что оптимизатор выполнит подзапрос один раз для каждой строки, что дороже, когда таблицы большие. По-настоящему хороший оптимизатор может сгладить вещи так, чтобы они были эквивалентны.
Используйте group by и max для фильтрации результатов соединения.
select * from Users as u
inner join HardwareAssignments as ha
on u.id = ha.userid
inner join Hardware as h
on uh.hardwareid = h.id
where ha.AssignedOn = (select max(assignedon)
from HardwareAssignments as ha2
where ha.userid = ha2.userid)
Это могло бы вас приблизить. Не уверен, что это точно.