2016-09-15 3 views
1

У меня есть две таблицы:Postgresql COALESCE не устанавливает значение по умолчанию

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 и total_price (car_price + цена включенных опций, цена которых равна 0).

Пример:

t1.id=2 для возвращения:

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

Проблема возникает, когда у меня нет, включенные с ценой УСТРОЙСТВА> 0, например t1.id = 1.

Что она возвращает :

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

Что мне нужно, это возврат только t1.car_price как total_ цена, если нет включенных опционных с ценой> 0:

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

Может кто-нибудь помочь мне с этой проблемой, пожалуйста?

ответ

1

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

2

Условие q1.id_car=1 в где пункте эффективно превращает ваш внешнее соединение в внутреннем соединении, поскольку для строк не соответствуют условию соединения q1.id_car будет аннулировано и сравнение =1 удалит эти строки снова.

Вы должны были бы положить, что в РЕГИСТРИРУЙТЕСЬ состояние - но у вас уже есть условие на id_car в производной таблице («q1»), вам не нужно в любом случае.

Другая возможность будет фильтровать по соответствующему значению из tcars таблицы: where t1.id = 1


Редактировать

Перемещая условия на столе t2, чтобы условие соединения вы получите что вы хотите:

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 i s, определяемый как первичный ключ в tcars, то достаточно group by t1.id.

Смотрите пример здесь: http://rextester.com/YOYF30261

+0

Мне нужна q1.id_car = 1; для возврата цены на конкретный автомобиль, если я удалю эту строку, запрос вернет цену для всех автомобилей в моем db – Kuzuri

+0

@ Kuzuri: вы можете ограничить общий результат только одним автомобилем, используя 'where t1.id = 1 ' –

+0

Я знаю, что мне нужно от этого запроса, чтобы вернуть только цену автомобиля, если у меня нет включенных опций. Предположим, что у меня две машины: id = 1, id = 2 в tcars и id_car = 1, id_car = 2 в tcar_specs. Цена первого автомобиля - 1000, и у меня есть два дополнительных варианта (первая - 100 и вторая 150), запрос вернется 1250, цена второго автомобиля (id_car = 2) - 900, и у меня нет включенных опционных, для этого автомобиля запрос должен вернуть 900, но это не так, он ничего не возвращает. – Kuzuri

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 
+0

Тот же результат, нет строки, если я не включил опциональные опции – Kuzuri

+0

Это просто невозможно , Вы что-то изменили в моем запросе? См. [SqlFiddle] (http://sqlfiddle.com/#!15/07296/1) – klin

Смежные вопросы