Postgresql COALESCE没有设置默认值

时间:2016-09-15 11:48:41

标签: sql postgresql outer-join

我有两张桌子:

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

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

示例:

for t1.id=2返回:

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

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

它返回的内容:

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

我需要的是,如果没有包含价格> 0的选项,则只返回t1.car_price作为total_price:

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

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

3 个答案:

答案 0 :(得分:2)

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

您需要将其置于 JOIN条件中 - 但由于您已在派生表(“q1”)中的=1上有条件,因此您不需要无论如何。

另一种可能性是过滤id_car表中的相应值:tcars

修改

通过将t2表上的条件移动到连接条件,您可以得到您想要的结果:

where t1.id = 1

如果将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就足够了。

请参阅此处的示例:http://rextester.com/YOYF30261

答案 1 :(得分:2)

首先应该在第二个表中加入包含所有条件的表,并从这个(连接)结果中聚合值,例如:

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

答案 2 :(得分:1)

&#13;
&#13;
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=$1
&#13;
&#13;
&#13;