对于每个唯一的条目,包括另一个列表中的所有行



我有两个这样的表:

汽车:包含每辆汽车的部分零件的价格

| 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 joinnot exists在本文中几乎相同。不过,在insert查询中,我通常使用not exists,因为我认为其意图更清晰。

最新更新