使用下面的表作为示例并将列出的查询作为基本查询,我想添加一种方法来仅选择具有最大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的行!
如果这是不可能的,我将不胜感激,建议如何在不大幅增加搜索执行时间的情况下实现我的目标!
如果你想保持逻辑,这就是我要做的:
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)