MySQL选择具有最大id并匹配其他条件的行

Tri*_*tan 4 mysql max

使用下面的表作为示例并将列出的查询作为基本查询,我想添加一种方法来仅选择具有最大id的行!无需进行第二次查询!

TABLE VEHICLES

id      vehicleName
-----   --------
1       cool car
2       cool car
3       cool bus
4       cool bus
5       cool bus
6       car
7       truck
8       motorcycle
9       scooter
10      scooter
11      bus

TABLE VEHICLE NAMES

nameId  vehicleName
------  -------
1       cool car
2       cool bus
3       car
4       truck
5       motorcycle
6       scooter
7       bus

TABLE VEHICLE ATTRIBUTES

nameId  attribute
------  ---------
1       FAST
1       SMALL
1       SHINY
2       BIG
2       SLOW
3       EXPENSIVE
4       SHINY
5       FAST
5       SMALL
6       SHINY
6       SMALL
7       SMALL
Run Code Online (Sandbox Code Playgroud)

和基本查询:

select a.*
  from vehicle         a
  join vehicle_names   b using(vehicleName)
  join vehicle_attribs c using(nameId)
 where c.attribute in('SMALL', 'SHINY')
 and a.vehicleName like '%coo%'
 group 
    by a.id
having count(distinct c.attribute) = 2;
Run Code Online (Sandbox Code Playgroud)

所以我想要实现的是选择具有某些属性的行,这些属性与名称匹配,但每个名称只有一个条目匹配id最高的位置!

因此,此示例中的工作解决方案将返回以下行:

id      vehicleName
-----   --------
2       cool car
10      scooter
Run Code Online (Sandbox Code Playgroud)

如果它在id上使用某种最大值

目前,我得到了酷车和踏板车的所有参赛作品.

我的真实世界数据库遵循类似的结构,其中包含数千个条目,因此上面的查询可以轻松返回3000多个结果.我将结果限制为100行以保持执行时间较低,因为结果用于我的网站上的搜索.我重复使用相同名称但只有不同ID的"车辆"的原因是新车型不断添加,但我保留旧车型,以便那些想要挖掘它们的人!但是在汽车名称的搜索中,我不想退回旧卡,而是最新的卡,即ID最高的卡!

正确的答案将适应我上面提供的我正在使用的查询,并且只返回名称匹配但具有最高ID的行!

如果这是不可能的,我将不胜感激,建议如何在不大幅增加搜索执行时间的情况下实现我的目标!

Dan*_*ure 5

如果你想保持逻辑,这就是我要做的:

select a.*
from vehicle a
    left join vehicle a2 on (a.vehicleName = a2.vehicleName and a.id < a2.id)
    join vehicle_names   b on (a.vehicleName = b.vehicleName)
    join vehicle_attribs c using(nameId)
where c.attribute in('SMALL', 'SHINY')
    and a.vehicleName like '%coo%'
    and a2.id is null
group by a.id
having count(distinct c.attribute) = 2;
Run Code Online (Sandbox Code Playgroud)

哪个产量:

+----+-------------+
| id | vehicleName |
+----+-------------+
|  2 | cool car    |
| 10 | scooter     |
+----+-------------+
2 rows in set (0.00 sec)

正如其他人所说,规范化可以在几个层面上完成:

保持当前vehicle_names表作为主查找表,我会改变:

update vehicle a
    inner join vehicle_names b using (vehicleName)
set a.vehicleName = b.nameId;
alter table vehicle change column vehicleName nameId int;

create table attribs (
    attribId int auto_increment primary key,
    attribute varchar(20),
    unique key attribute (attribute)
);
insert into attribs (attribute)
    select distinct attribute from vehicle_attribs;
update vehicle_attribs a
    inner join attribs b using (attribute)
set a.attribute=b.attribId;
alter table vehicle_attribs change column attribute attribId int;
Run Code Online (Sandbox Code Playgroud)

这导致了以下查询:

select a.id, b.vehicleName
from vehicle a
    left join vehicle a2 on (a.nameId = a2.nameId and a.id < a2.id)
    join vehicle_names b on (a.nameId = b.nameId)
    join vehicle_attribs c on (a.nameId=c.nameId)
    inner join attribs d using (attribId)
where d.attribute in ('SMALL', 'SHINY')
    and b.vehicleName like '%coo%'
    and a2.id is null
group by a.id
having count(distinct d.attribute) = 2;
Run Code Online (Sandbox Code Playgroud)