MySQL离开了加入和联盟

时间:2018-04-17 19:21:42

标签: mysql join union

拥有这样的数据库结构:

id, name, color
1, mercedes, red
2, volvo, blue
3, bmw, green

car_alt

id, car_id, color
1, 1, green
2, 1, blue
3, 2, red
4, 2, blue

我想得到这样的结果:

id, name, color
1, mercedes, red
1, mercedes, green
1, mercedes, blue
2, volvo, blue
2, volvo, red
2, volvo, blue
3, bmw, green

目前我使用此查询:

SELECT id, name, color
FROM car
UNION
SELECT car.id, car.name, car_alt.color
FROM car
INNER JOIN car_alt ON car.id = car_alt.id_car

有没有办法不使用UNION?我想知道是否可以使用LEFT JOIN添加一些空行,如:

SELECT car.id, car.name, COALESCE(car_alt.color, car.color)
FROM car
LEFT JOIN car_alt ON car.id = car_alt.id_car OR 'GET EMPTY ROW'

要解释为什么我甚至会问这个,当我必须将更多表连接到表car时,我的查询看起来像:

SELECT id, name, color,
t1.col, t2.col, t3.col, ...
FROM car
JOIN t1
JOIN t2
JOIN t3
...
UNION
SELECT car.id, car.name, car_alt.color,
t1.col, t2.col, t3.col, ...
FROM car
JOIN t1
JOIN t2
JOIN t3
...
INNER JOIN car_alt ON car.id = car_alt.id_car

所以这里有很多重复。我想到的另一种方法是将UNION移动到子查询,例如

SELECT car.id, car.name, union.color,
t1.col, t2.col, t3.col, ...
FROM car
JOIN t1
JOIN t2
JOIN t3
...
INNER JOIN (
SELECT car.id, car.color
FROM car
UNION
SELECT car_alt.car_id, car_alt.color
FROM car_alt) union ON car.id = union.id

2 个答案:

答案 0 :(得分:0)

如果没有union / union all,我不相信有合理的方法可以做到这一点。

这是不合理的方法,使用cross join并过滤:

select c.id, c.name, co.color
from (select distinct id, name from car) c cross join
     (select distinct color from car) co 
where exists (select 1 from car c2 where c2.id = c.id and c2.color = co.color) or
      exists (select 1 from car_alt ca where ca.id = c.id and ca.color = co.color);

这基本上重构了逻辑,因此or在功能上完成了union all在你的版本中的作用。

答案 1 :(得分:0)

如果您不想使用UNION,临时表怎么样?

branch

请完成后不要忘记DROP TABLE #Temp - 清理它是件好事。