给定以下示例数据:
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;
这和 Justin Niessner 的答案之间的区别在于子查询出现的位置;在这里,我在 FROM 子句中创建了它。这几乎可以保证它被执行一次。当 Justin 的回答中的 WHERE 子句中有一个相关的子查询时,优化器可能会为每一行执行一次子查询——当表很大时,这会更昂贵。一个真正优秀的优化器可能会将事物扁平化,使两者等价。
关于SQL仅加入最大行拼图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2601663/