从一组中选择一个值进行选择

时间:2020-08-05 13:56:38

标签: mysql distinct

我有以下sql查询

select devices_device.id , devices_device.code, sss.id as "site_id", sss.name as "site_name"
from devices_device
inner join st_site_site sss on devices_device.site_id = sss.id
where devices_device.deleted = false
order by devices_device.id, devices_device.start_date

我现在获得设备ID的列表。其中一些是相同的。我想做一个不同的记录,所以我只保留每个设备的第一条记录(由于在start_date排序,这将是该设备的最新设备记录)

我该怎么做?如果我这样做

select distinct devices_device.id , devices_device.code, sss.id as "site_id", sss.name as "site_name"
from devices_device
inner join st_site_site sss on devices_device.site_id = sss.id
where devices_device.deleted = false
order by devices_device.id, devices_device.start_date

什么都没发生

3 个答案:

答案 0 :(得分:1)

您可以使用ROW_NUMBER()窗口函数来标识所需的行。然后,滤除其他内容很容易。

例如:

select *
from (
  select
    d.id, d.start_date, d.code, 
    s.id as "site_id", s.name as "site_name", 
    row_number() over(partition by d.id order by start_date desc) as rn
  from devices_device d
  inner join st_site_site s on d.site_id = s.id
  where d.deleted = false
) x
where rn = 1
order by id, start_date

在此查询中,每个设备组中的最新行的ROW_NUMBER()值将为1。这样一来,最后的过滤就会删除所有大于1的其他行。

注意:如果发生冲突(两行具有相同的最近start_date),此查询将始终在它们之间返回 [尽管随机]行。

答案 1 :(得分:0)

您可能应该使用GROUP BY。像这样:

select distinct devices_device.id , devices_device.code, sss.id as "site_id", 
sss.name as "site_name"
from devices_device
inner join st_site_site sss on devices_device.site_id = sss.id
where devices_device.deleted = false
group by devices_device.id
order by devices_device.start_date

答案 2 :(得分:0)

您可以测试最小开始日期

drop table if exists devices_device,st_site_site;
create table devices_device(id int,code int,site_id int,start_date date,deleted int);
create table st_site_site(id int,name varchar(10));
insert into devices_device values(1,10,1,'2020-10-01',0),(1,20,1,'2020-09-01',0);
insert into st_site_site values(1,'aaa');

select devices_device.id , devices_device.code, sss.id as "site_id", sss.name as "site_name"
from devices_device
inner join st_site_site sss on devices_device.site_id = sss.id
where devices_device.deleted = false and
        devices_device.start_date = (select min(d1.start_date) from devices_device d1 where d1.id = devices_device.id)
order by devices_device.id;

+------+------+---------+-----------+
| id   | code | site_id | site_name |
+------+------+---------+-----------+
|    1 |   20 |       1 | aaa       |
+------+------+---------+-----------+
1 row in set (0.001 sec)