Postgresql COALESCE 没有设置默认值

Postgresql COALESCE does not set default value

我有两个表:

tcars

 id  |         name        |  car_price 
 ----|---------------------|------------
  1  |First_car_name       |       1000 
  2  |Second_car_name      |       1200 

tcar_optionals

 id | id_car   | spec |  opt_included   |price
----|----------|------|-------------------------
 1  |       2  |Spec1 |  true           |   500 
 2  |       2  |Spec2 |  true           |   100 
 3  |       2  |Spec3 |  false          |   500 
 4  |       2  |Spec4 |  true           |     0 
 5  |       1  |Spec5 |  false          |   500 
 6  |       1  |Spec6 |  true           |     0 

以及以下查询:

select t1.id, coalesce(t1.car_price, 0)+ coalesce(sum(t2.price), 0) as total_price
from tcars t1
    left join tcar_optionals t2 on t2.id_car = t1.id
where t2.opt_included and t2.price>0 and t1.id=?
group by t1.id, t1.car_price

它 return 是来自 tcars 的 id 和 total_price(car_price+价格>0 的包含选项的价格)。

示例:

for t1.id=2 returns:

 id | total_price
----|------------
 2  | 1800

当我没有包含价格>0 的可选商品时出现问题,例如 t1.id = 1。

什么 returns:

 id | total_price
----|------------

我需要的是 return 只有 t1.car_price 和 total_price 如果没有包含价格>0 的选项:

 id | total_price
----|------------
 1  |      1000  

有人可以帮我解决这个问题吗?

where 子句中的条件 q1.id_car=1 有效地将您的外部连接转变为内部连接,因为对于不匹配连接条件的行 q1.id_car 将是null 和比较 =1 将再次删除这些行。

您需要将其放入 JOIN 条件 - 但因为您已经在派生的 table 中对 id_car 设置了条件("q1"), 反正你不需要它。

另一种可能性是从 tcars table 中过滤相应的值:where t1.id = 1


编辑

通过将 t2 table 上的条件移动到连接条件,您确实得到了您想要的:

select t1.id, coalesce(t1.car_price, 0) + coalesce(sum(t2.price), 0) as total_price
from tcars t1
    left join tcar_optionals t2 
           on t2.id_car = t1.id 
          and t2.opt_included and t2.price > 0 --<< conditions for tcar_optionals go here
where t1.id = 1   --<< limit the car you want to see
group by t1.id;

如果id定义为tcars中的主键,那么group by t1.id就够了。

参见此处示例:http://rextester.com/YOYF30261

您应该首先在第二个 table 上加入具有所有条件的 table 并从这个(加入的)结果中聚合值,例如:

select id, coalesce(car_price, 0)+ coalesce(sum(price), 0) total_price
from tcars
left join tcar_optionals on id = id_car and spec_included
-- where id = 1
group by id, car_price

select (t1.car_price + coalesce(extra_price, 0)) as start_price
from tcars t1
left join (select id_car,sum(price) as extra_price from tcar_optionals 
where opt_included and price > 0 group by 1) q1 on q1.id_car = t1.id
where t1.id=