SQL仅加入最大行拼图

Bil*_*eal 9 mysql sql join

给出以下示例数据:

  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    |
+---------+-------------+-------------+
Run Code Online (Sandbox Code Playgroud)

我想编写一个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    |
+--------------------+------------+-----------+----------------+---------------+-------------+
Run Code Online (Sandbox Code Playgroud)

我的麻烦是,每个用户需要为每个用户选择最大的"Assigned On"日期并用于实际加入...

在SQL中有一种聪明的方法吗?

Jon*_*ler 9

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;
Run Code Online (Sandbox Code Playgroud)

这与Justin Niessner的答案之间的区别在于子查询出现的地方; 在这里,我在FROM子句中创建了它.这几乎可以保证它被执行一次.当在Justin的答案中WHERE子句中存在相关的子查询时,优化器可能会为每一行执行一次子查询 - 这在表很大时会更昂贵.一个非常好的优化器可能会使事情变得扁平,以便两者相等.


Jus*_*ner 8

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)
Run Code Online (Sandbox Code Playgroud)

这可能会让你接近.不确定它是否确切.