我有以下SQL表,并且需要兼容MySQL和Postgresql的解决方案
create table price_level (
id serial primary key,
name varchar(200)
);
create table product (
id serial primary key,
name varchar(200),
base numeric not null,
vat int not null
);
create table product_price (
id serial primary key,
base numeric,
vat numeric,
product_id int not null references product(id) on update cascade on delete cascade,
price_level_id int not null references price_level(id) on update cascade on delete cascade,
unique(product_id,price_level_id)
);
对于上面的SQL结构,我创建了一个视图:
create view view_product as
select
p.id as product_id,
coalesce(pp.base, p.base) as base,
coalesce(pp.vat, p.vat) as vat,
pp.price_level_id
from
product as p
left join
product_price as pp on pp.product_id=p.id
;
这些是样本数据:
表 price_level
id name
1 A
2 B
3 C
4 D
5 E
表产品
id name base vat
1 Test 100 20
表 product_price
id base vat product_id price_level_id
1 NULL NULL 1 1
2 200 NULL 1 2
3 NULL 10 1 3
视图 view_product 的输出为:
product_id base vat price_level_id
1 100 20 1
1 200 20 2
1 100 10 3
...问题是:如何获得这样的输出?:
product_id base vat price_level_id
1 100 20 1
1 200 20 2
1 100 10 3
1 100 20 4
1 100 20 5
正如您在上面的示例中所看到的,我需要将 D 和 E price_level作为附加行。如何创建此类视图/加入?它应该具有良好的性能,因为表格可以通过额外的价格水平变大。
感谢您的帮助。
答案 0 :(得分:0)
我会使用union
从price_level
表中添加那些在product_price
表中没有相应记录的特定产品的记录:
select
p.id as product_id,
coalesce(pp.base, p.base) as base,
coalesce(pp.vat, p.vat) as vat,
pp.price_level_id
from
product as p
left join
product_price as pp on pp.product_id=p.id
union distinct
select
p.id as product_id,
p.base,
p.vat,
pl.price_level_id
from
price_level pl
join
product as p
where (p.id, pl.id) not in (select product_id, price_level_id from product_price)
答案 1 :(得分:0)
我会使用以下方法,交叉连接表price_level和product。然后只查找product_price表中是否存在覆盖。
SELECT
product.id as product_id,
IFNULL(product_price.base, product.base) as `base`,
IFNULL(product_price.vat, product.vat) as `vat`,
price_level.id as price_level_id
FROM price_level
CROSS JOIN product
LEFT JOIN product_price ON
product_price.price_level_id = price_level.id AND
product_price.product_id = product.id
WHERE product.id = 1
ORDER BY product.id, price_level.id
请记住在WHERE条件
中使用product.id而不是product_id答案 2 :(得分:-1)
尝试:
create view view_product as
select
p.id as product_id,
coalesce(pp.base, p.base) as base,
coalesce(pp.vat, p.vat) as vat,
coalesce(pp.price_level_id,pl.id) --modified row
from
product as p
left join
product_price as pp on pp.product_id=p.id
LEFT JOIN price_level pl on pp.price_level_id=pl.id -- modified row
;
(未经测试,但肯定你必须从正确的表中捕捉价格水平)