假设我有一张车辆表:
v color col3 col4 col5 .....
car red
train gray
plane white
car blue
bike black
(1000 more)
包含分类的表格:
prio v color class
1 car red C1
2 car % F3
3 plane % W1
4 bike blue B4
5 bike white B8
6 bike % O9
分类表很小,小于100.只有一个查找表。如有必要,我们可以向车辆添加id
列。
现在我想将分类添加到车辆表中。车辆中的行数不得更改。 结果应该是:
v color class
car red C1
train gray
plane white W1
car blue F3
bike black O9
(1000 more)
现在,如果我这样做
SELECT vehicles v
LEFT JOIN classifications c ON v.v LIKE c.v AND v.color LIKE c.color
我得到重复的条目,因为分类匹配不是唯一的。例如,白色自行车匹配规则5和6,在这种情况下,必须采用规则5,因为它具有较低的prio
。
如何避免重复?
答案 0 :(得分:3)
您可以使用相关查询和LIMIT
:
SELECT v.*,
(SELECT c.class FROM classifications c
WHERE v.v like c.v AND v.color LIKE c.color
ORDER BY c.prio LIMIT 1) AS class
FROM vehicles v
虽然我不明白你为什么要使用LIKE
如果你正在寻找完全匹配,我认为这会更快:
c.color IN(v.color,'%')
LIKE
用于部分字符串比较,它是一个真正的性能杀手!所以尽量避免使用它。
答案 1 :(得分:0)
不同怎么样?
select distinct vehicles v left join classifications c
on v.v like c.v and v.color like c.color
我现在无法尝试,但这应该足以满足您的要求......
答案 2 :(得分:0)
编辑:此查询无效,如下面的评论中所述。无论如何,我会留下这个答案用于学习目的。
您可以使用汇总函数group by, having
和min
函数
select * from vehicles v
left join classifications c on v.v like c.v and v.color like c.color
group by v.v
having MIN(prio)
这将按车辆分组结果,然后选择优先级最低的行。
答案 3 :(得分:0)
SELECT *
FROM vehicles v
LEFT JOIN classifications c ON
c.prio=
(SELECT prio FROM classifications c
WHERE v.v like c.v AND v.color LIKE c.color
ORDER BY c.prio LIMIT 1)
这假定“prio”是唯一的。
答案 4 :(得分:0)
如果你想避免使用相关的子查询(这取决于数据可能会导致性能问题,因为它需要MySQL为每个返回的行执行子查询),那么还有其他几个选项: - < / p>
有一个子查询,为每个车辆/颜色带回最小prio(所以这个子查询执行一次),并将其加入车辆,颜色和最小值匹配的分类表
SELECT v.v,
v.color,
c.class
FROM vehicles v
LEFT OUTER JOIN
(
SELECT v, color, MIN(prio) AS min_prio
FROM classifications
GROUP BY v, color
) sub0
ON v.v = sub0.v AND v.color = sub0.color
LEFT JOIN classifications c ON sub0.v = c.v AND sub0.color = c.color AND sub0.min_prio = c.prio
另一种选择是滥用GROUP_CONCAT功能。这确实假设类字段不包含任何逗号(如果它可能那么你可以使用另一个分隔符)。
SELECT v.v,
v.color,
SUBSTRING_INDEX(GROUP_CONCAT(c.class ORDER BY prio), ',', 1) AS class
FROM vehicles v
LEFT JOIN classifications c ON v.v = c.v AND v.color = c.color
GROUP BY v.v,
v.color