我有两个这样的表:
汽车:包含每辆汽车的部分零件的价格
| Car | Parts | Price |
| -------- | -------------- | -------|
| A | Windshield | 100 |
| A | Rims | 50 |
| B | Bumper | 200 |
| B | Rims | 60 |
零件:包含汽车的所有可能零件
| Parts |
|--------------|
| Windshield |
| Rims |
| Bumper |
| Headlights |
我希望汽车中的每辆车都有零件的每个条目。最终结果应该是这样的:
| Car | Parts | Price |
| -------- | -------------- | -------|
| A | Windshield | 100 |
| A | Rims | 50 |
| A | Bumper | 0 |
| A | Headlights | 0 |
| B | Bumper | 200 |
| B | Rims | 60 |
| B | Windshield | 0 |
| B | Headlights | 0 |
关于我该怎么做有什么想法吗?
PS:订单无关紧要
您可以使用日历表方法:
SELECT c.Car, p.Parts, COALESCE(t.Price, 0) AS Price
FROM (SELECT DISTINCT Car FROM cars) c
CROSS JOIN parts p
LEFT JOIN cars t
ON t.Car = c.Car AND t.Parts = p.Parts
ORDER BY c.Car, p.Parts;
但正如@Larnu在评论中正确指出的那样,你的模式应该有一个单独的表,包含所有的汽车。这将避免我在上面的回答中有明显的选择。
如果您想将附加行插入到cars
中,那么代码看起来像:
insert into cars (car, parts, price)
select c.car, p.part, 0
from (select distinct car from cars) c cross join
parts p
where not exists (select 1
from cars c2
where c2.car = c.car and c2.part = c.part
);
这将生成汽车和零件的所有组合。然后它过滤掉cars
中不存在的那些。
请注意,left join
和not exists
在本文中几乎相同。不过,在insert
查询中,我通常使用not exists
,因为我认为其意图更清晰。