对于糟糕的头衔感到抱歉,但很难用一行来解释。
我有一个窗口小部件数据表 - 每个记录都有一个id,创建的时间戳,device_id(外部密钥)和状态('prelim'或'official')。我试图获得每个设备的单一,最新,“最官方”记录 - 这意味着我想要最新的官方记录,但如果没有官方记录,最新的预备记录。实施例
ID | created | device_id | status | data
1 | 100 | A | prelim | ##
2 | 105 | A | prelim | ##
3 | 107 | B | official | ##
4 | 109 | B | prelim | ##
我应该得到第2行,因为它没有正式记录,它是设备A和第3行的最新记录,因为它是设备B的最新官方记录(应该忽略官方记录之后的任何预备记录)
目前,我正在使用此查询:
Select widget.* from widget
INNER JOIN (select id, device_id, status, max(created) as created from widget
group by device_id, status) max_widget
on widget.created = max_widget.created and widget.device_id = max_widget.device_id
此查询为我提供了按设备和状态分组的最新行,因此在设备B的情况下,它返回2行 - 而不是我需要的行。
如何限制联接仅返回官方行(如果存在)。我觉得我应该能够通过内部查询的位置或者join子句中的coalesce()解决这个问题,但是我不能完全围绕它解决这个问题。
感谢。
答案 0 :(得分:2)
您可以使用相关的子查询:
select *
from widget w
where id = (
select id
from widget x
where w.device_id = x.device_id
order by field(status, 'official', 'prelim'), created desc
limit 1
);
order by field(status, 'official', 'prelim')
首先保留“官方”记录,created desc
保留最新记录。 limit 1
获取一行,我们可以在where子句中使用。
答案 1 :(得分:0)
create table widget (
id smallint,
created smallint,
device_id char(1),
status varchar(20),
data varchar(20));
insert into widget (id, created, device_id, status, data) values (1,100,'A','prelim','abcd1234');
insert into widget (id, created, device_id, status, data) values (2,105,'A','prelim','efgh5678');
insert into widget (id, created, device_id, status, data) values (3,107,'B','official','ijkl9012');
insert into widget (id, created, device_id, status, data) values (4,109,'B','prelim','mnop3456');
select max(a.created),
a.device_id,
case
when b.id is null
then a.status
else b.status
end as status
from widget a
left join widget b
on a.device_id = b.device_id
and b.status = 'official'
where (
(a.status = 'prelim'
and b.status is null)
or
(b.status = 'official'
and a.status <> 'prelim')
)
group by a.device_id,
case
when b.id is null
then a.status
else b.status
end;
输出:
+----------------+-----------+----------+
| max(a.created) | device_id | status |
+----------------+-----------+----------+
| 105 | A | prelim |
| 107 | B | official |
+----------------+-----------+----------+
2 rows in set (0.00 sec)