我的SQL Server数据库中有两个表要加入:
人员表:
PersonId Name DeviceId
001 John 11111
002 Eric 22222
003 Steve 33333
设备表:
DeviceId Date
11111 2013-02-01
11111 2013-02-02
11111 2013-02-03
22222 2013-02-03
22222 2013-02-01
我想要的结果是以下
PersonId Name DeviceId Date IsRegistered
001 John 11111 2013-02-03 1
002 Eric 22222 2013-02-03 1
003 Steve 33333 null 0
因此,当你看到我希望表之间的连接时,我只想要唯一的值。
数据字段应该是最后注册的(最新日期)。如果此人在日期字段中有值,则IsRegistered
应具有值0
如果有人知道如何解决这个问题我会很感激
答案 0 :(得分:4)
查询:
SELECT
p.*, d.maxdate
FROM persons p
left join
( SELECT id, MAX(date) MaxDate
FROM device
GROUP BY id
) d ON p.deviceid = d.id
ORDER BY d.maxdate DESC;
| PERSONID | NAME | DEVICEID | MAXDATE |
-----------------------------------------------------------------
| 1 | John | 11111 | February, 03 2013 02:00:00+0000 |
| 2 | Eric | 22222 | February, 03 2013 00:00:00+0000 |
| 3 | Steve | 33333 | (null) |
我发现您还需要isRegistered
列,此处为:
查询:
SELECT
p.*, d.maxdate, case when d.maxdate is null then 0 else 1 end as isRegistered
FROM persons p
left join
( SELECT id, MAX(date) MaxDate
FROM device
GROUP BY id
) d ON p.deviceid = d.id
ORDER BY d.maxdate DESC
;
结果:
| PERSONID | NAME | DEVICEID | MAXDATE | ISREGISTERED |
--------------------------------------------------------------------------------
| 1 | John | 11111 | February, 03 2013 02:00:00+0000 | 1 |
| 2 | Eric | 22222 | February, 03 2013 00:00:00+0000 | 1 |
| 3 | Steve | 33333 | (null) | 0 |
答案 1 :(得分:1)
试试这个:
SELECT
p.PersonId,
p.Name,
p.DeviceId,
d.MaxDate AS "Date",
CASE
WHEN d.deviceID IS NULL THEN 0
ELSE 1
END AS IsRegistred
FROM Person p
LEFT JOIN
(
SELECT DeviceId, MAX(Date) MaxDate
FROM Device
GROUP BY DeviceId
) d ON p.DeviceId = d. DeviceId;
这会给你:
| PERSONID | NAME | DEVICEID | DATE | ISREGISTRED |
-------------------------------------------------------------------------------
| 1 | John | 11111 | February, 03 2013 02:00:00+0000 | 1 |
| 2 | Eric | 22222 | February, 03 2013 02:00:00+0000 | 1 |
| 3 | Steve | 33333 | (null) | 0 |
或:使用排名功能ROW_NUMBER()
即可:
WITH CTE
AS
(
SELECT
p.PersonId,
p.Name,
p.DeviceId,
d.deviceID AS ddeviceID,
d.Date,
ROW_NUMBER() OVER(PARTITION BY p.PersonID, p.DeviceId
ORDER BY Date DESC) rownum
FROM Person p
LEFT JOIN Device d ON p.DeviceId = d. DeviceId
)
SELECT
PersonID,
Name,
DeviceId,
Date,
CASE
WHEN ddeviceID IS NULL THEN 0
ELSE 1
END AS IsRegistred
FROM CTE
WHERE rownum = 1;
这会给你相同的结果。