Oracle: подсчет и группировка по запросу не возвращают строк вместо 0

#sql #oracle

#sql #Oracle

Вопрос:

У меня есть запрос, который подсчитывает количество, acc_ene удовлетворяющих условию ene.ene_type = 'PRCECO' и deal.deal_scope = 'Y' , для данного run_id

Вот запрос :

 select run.run_id, 35, count(*), sysdate
from dt_runs run
join acc_deals deal on deal.deal_cnt_id = run.deal_cnt_id
join acc_ene ene on ene.deal_id = deal.deal_id and ene.ene_cnt_id = run.ene_cnt_id
where ene.ene_type = 'PRCECO'
and deal.deal_scope = 'Y'
and run.run_id = 'amp;1'
group by run.run_id, 35, sysdate;
  

Однако, когда таковых acc_ene не существует, вместо возврата 0 запрос не возвращает строки.
Есть ли способ изменить мой запрос, чтобы он возвращал 0 ?

Я уже пробовал с nvl(count(*), 0) (-> не лучше) и этим запросом, который, казалось, сработал:

 select run.run_id, 34, (select count(*) from acc_ene ene where ene.ene_type = 'PRCECO'), sysdate
from dt_runs run, acc_deals deal, acc_ene ene 
where ene.deal_id = deal.deal_id
and ene.ene_cnt_id = run.ene_cnt_id
and deal.deal_scope = 'Y'
and run.run_id = 'amp;1'
and deal.deal_cnt_id = run.deal_cnt_id 
group by run.run_id, 34, sysdate;
  

Но затем я попробовал с другим ene.ene_type = 'IMM' , для которого, как я знаю, в таблице есть записи. Он вернул общее количество acc_ene типа 'IMM' вместо количества этого типа acc_ene для конкретного запуска.

Что я делаю не так?

Ответ №1:

Когда нет данных, и вы получили ГРУППУ, по которой нет результата, именно так работает SQL.

Попробуйте изменить это, используя вместо этого внешние соединения:

 select run.run_id, 35, count(ene.deal_id), sysdate
from dt_runs run
left join acc_deals deal 
  on deal.deal_cnt_id = run.deal_cnt_id
 and deal.deal_scope = 'Y'
left join acc_ene ene
  on ene.deal_id = deal.deal_id 
 and ene.ene_cnt_id = run.ene_cnt_id
 and ene.ene_type = 'PRCECO'
where run.run_id = 'amp;1'
group by run.run_id, 35, sys date;
  

Или избавьтесь от GROUP BY, вам просто нужны данные для одного run_id:

 select min(run.run_id), 35, count(*), sysdate
from dt_runs run
join acc_deals deal on deal.deal_cnt_id = run.deal_cnt_id
join acc_ene ene on ene.deal_id = deal.deal_id and ene.ene_cnt_id = run.ene_cnt_id
where ene.ene_type = 'PRCECO'
and deal.deal_scope = 'Y'
and run.run_id = 'amp;1';
  

Я не могу проверить, принимает ли Oracle константы без group by, в противном случае вам, возможно, придется использовать

 select min(run.run_id), min(35), count(*), min(sys date)