这与Get records with max value for each group of grouped SQL results有关,除了必要的组在单独的表中。
假设我有几座建筑物,每座建筑物都有一些办公室,并且有些人“签到”这些办公室来工作。
此表称为“办公室”,将建筑物与办公室匹配:
building office
---
Seuss Yertle
Seuss Cubbins
Milne Pooh
Milne Eeyore
Milne Roo
此表称为“签到”,记录了人们在每个办公室工作的时间:
id office person timestamp
---
1 Yertle Aaron 100
2 Cubbins Aaron 200
3 Pooh Aaron 300
4 Cubbins Charlie 300
5 Cubbins Aaron 700
6 Eeyore Beth 600
7 Pooh Beth 400
我想为每个建筑工人组合生成一张表格,告诉我该签到是该建筑中该人最近的一次入住:
building person checkin_id office timestamp
---
Seuss Aaron 5 Cubbins 700
Milne Aaron 3 Pooh 300
Milne Beth 6 Eeyore 600
Seuss Charlie 4 Cubbins 300
我不知道该怎么做。标准技巧包括在比较相关值时将表连接到自身,然后在没有较大值的情况下丢弃行。我假设我需要两个“ checkins”副本和两个“ buildings”副本,它们之间具有复杂的连接,但是我似乎无法在正确的位置显示NULL。
我正在使用MySQL,如果有帮助的话。
答案 0 :(得分:1)
有一个使用group_concat()
和substring_index()
的技巧,您可以使用一个group by
来做到这一点:
select o.building, c.person,
max(c.id) as checkinid,
substring_index(group_concat(c.office order by timestamp desc), ',', 1) as office,
max(c.timestamp) as timestamp
from offices o join
checkins c
on o.office = c.office
group by o.building, c.person;
此版本假定id
和timestamp
一起增加,因此max()
可以同时使用。
此外,group_concat()
(默认情况下)的中间结果限制为大约1,000个字符,因此,如果一个人/建筑物组合有很多办公室,或者如果办公室名字很长。当然,如果逗号出现在office
名称中,则可以更改分隔符。
答案 1 :(得分:0)
使用相关子查询
select b.* from
(select o.building,c.person,c.id as checkinid,
c.office,c.timestamp from
offices o join checkins c
on o.office=c.office
) b
where b.timestamp = (select max(a.timestamp)
from (
select o.building,c.person,
c.office,c.timestamp from
offices o join checkins c
on o.office=c.office
) as a where a.building=b.building and
a.person=b.person
)
order by person
输出
building person checkinid office timestamp
Milne Aaron 3 Pooh 300
Seuss Aaron 5 Cubbins 700
Milne Beth 6 Eeyore 600
Seuss Charlie 4 Cubbins 300
答案 2 :(得分:0)
要获得所需的结果,您必须创建一个表,其中包含每个办公室的所有签到位置(JOIN
offices
至checkins
),然后JOIN
每个建筑物中每个人的最新签到表:
SELECT o.building, c.person, c.id AS checkin_id, c.office, c.timestamp
FROM offices o
JOIN checkins c ON c.office = o.office
JOIN (SELECT o.building, c.person, MAX(c.timestamp) AS timestamp
FROM offices o
JOIN checkins c ON c.office = o.office
GROUP BY o.building, c.person) t ON t.building = o.building AND t.person = c.person AND t.timestamp = c.timestamp
ORDER BY c.person, c.office
输出:
building person checkin_id office timestamp
Seuss Aaron 5 Cubbins 700
Milne Aaron 3 Pooh 300
Milne Beth 6 Eeyore 600
Seuss Charlie 4 Cubbins 300