#oracle
#Oracle
Вопрос:
У меня есть запрос Oracle для получения цен на продукты для каждого клиента, но он возвращает строку только тогда, когда клиент устанавливает цену для каждого продукта (1, 4, 6, 189, 191, 7, 80, 235).
Как я могу сделать так, чтобы он возвращал строку, даже если 1 столбец равен нулю? Я хочу строку для каждого клиента, не имеет значения, есть ли у них цена на продукт или нет.
Я попробовал также полное внешнее соединение, левое внешнее соединение в таблицах цен, но это не повлияло на результат.
Пример того, что я хочу:
900001,Some Customer,1.59,2.49,3.39,0,0,0,0,4.92
select
ltrim(kust.kunr),
kust_adr.ku_name,
p1.sp_auf_m2,
p2.sp_auf_m2,
p3.sp_auf_m2,
p4.sp_auf_m2,
p5.sp_auf_m2,
p6.sp_auf_m2,
p7.sp_auf_m2,
p8.sp_auf_m2
from
kust
inner join
kust_adr
on kust.kunr = kust_adr.ku_nr
full outer join
sp_przu p1
on kust.kunr = p1.kunr
full outer join
sp_przu p2
on kust.kunr = p2.kunr
full outer join
sp_przu p3
on kust.kunr = p3.kunr
full outer join
sp_przu p4
on kust.kunr = p4.kunr
full outer join
sp_przu p5
on kust.kunr = p5.kunr
full outer join
sp_przu p6
on kust.kunr = p6.kunr
full outer join
sp_przu p7
on kust.kunr = p7.kunr
full outer join
sp_przu p8
on kust.kunr = p8.kunr
where
kust_adr.ku_adr_art = 0
and p1.prl_nr = 2
and p1.spr_nr = 1
and p2.prl_nr = 2
and p2.spr_nr = 4
and p3.prl_nr = 2
and p3.spr_nr = 6
and p4.prl_nr = 2
and p4.spr_nr = 189
and p5.prl_nr = 2
and p5.spr_nr = 191
and p6.prl_nr = 2
and p6.spr_nr = 7
and p7.prl_nr = 2
and p7.spr_nr = 80
and p8.prl_nr = 2
and p8.spr_nr = 235
order by
kust.kunr;
Комментарии:
1. Добро пожаловать в Stack Overflow. Одним из требований для публикации вопроса здесь является то, что это минимальное представление проблемы, с которой вы столкнулись. Запрос с 8 объединениями в нем не считается минимальным. Пожалуйста, упростите свой вопрос или, по крайней мере, выделите, где в запросе проблема.
2. Вы могли бы попробовать что-то в виде » и (p1.prl_nr = 2 или p1.prl_nr равно НУЛЮ) » для каждого из условий в предложении where
Ответ №1:
Ваши and
предложения превращают внешние соединения обратно во внутренние — переместите их в соответствующие предложения on:
select
ltrim(kust.kunr),
kust_adr.ku_name,
p1.sp_auf_m2,
p2.sp_auf_m2,
p3.sp_auf_m2,
p4.sp_auf_m2,
p5.sp_auf_m2,
p6.sp_auf_m2,
p7.sp_auf_m2,
p8.sp_auf_m2
from
kust
inner join
kust_adr
on kust.kunr = kust_adr.ku_nr
full outer join
sp_przu p1
on kust.kunr = p1.kunr
and p1.prl_nr = 2
and p1.spr_nr = 1
full outer join
sp_przu p2
on kust.kunr = p2.kunr
and p2.prl_nr = 2
and p2.spr_nr = 4
full outer join
sp_przu p3
on kust.kunr = p3.kunr
and p3.prl_nr = 2
and p3.spr_nr = 6
full outer join
sp_przu p4
on kust.kunr = p4.kunr
and p4.prl_nr = 2
and p4.spr_nr = 189
full outer join
sp_przu p5
on kust.kunr = p5.kunr
and p5.prl_nr = 2
and p5.spr_nr = 191
full outer join
sp_przu p6
on kust.kunr = p6.kunr
and p6.prl_nr = 2
and p6.spr_nr = 7
full outer join
sp_przu p7
on kust.kunr = p7.kunr
and p7.prl_nr = 2
and p7.spr_nr = 80
full outer join
sp_przu p8
on kust.kunr = p8.kunr
and p8.prl_nr = 2
and p8.spr_nr = 235
where
kust_adr.ku_adr_art = 0
order by
kust.kunr;
Я не уверен, действительно ли они должны быть полными внешними соединениями в любом случае; и, возможно, было бы проще использовать одно внешнее соединение на основе пар значений, а затем повернуть этот результат, например:
select *
from (
select
ltrim(k.kunr) as kunr,
ka.ku_name,
p.spr_nr,
p.sp_auf_m2
from
kust k
inner join
kust_adr ka
on k.kunr = ka.ku_nr
left outer join
sp_przu p
on k.kunr = p.kunr
and p.prl_nr = 2
and p.spr_nr in (1, 4, 6, 189, 191, 7, 80, 235)
where
ka.ku_adr_art = 0
)
pivot (
max(sp_auf_m2) for (spr_nr) in (1, 4, 6, 189, 191, 7, 80, 235)
)
order by
kunr;
хотя вы можете захотеть установить псевдонимы вместо того, чтобы использовать имена столбцов, указанные в кавычках по умолчанию, соответствующие spr_nr
значениям.
ORA-00933: команда SQL не завершена должным образом… это 10g
pivot
Предложение не было добавлено до 11g, но вы можете повторить то, что оно делает, с помощью агрегированных выражений case (и в любом случае оно фактически делает это под капотом):
select
ltrim(k.kunr) as kunr,
ka.ku_name,
max(case when p.spr_nr = 1 then p.sp_auf_m2 end) as sp_auf_m2_1,
max(case when p.spr_nr = 4 then p.sp_auf_m2 end) as sp_auf_m2_4,
max(case when p.spr_nr = 6 then p.sp_auf_m2 end) as sp_auf_m2_6,
max(case when p.spr_nr = 189 then p.sp_auf_m2 end) as sp_auf_m2_189,
max(case when p.spr_nr = 191 then p.sp_auf_m2 end) as sp_auf_m2_191,
max(case when p.spr_nr = 7 then p.sp_auf_m2 end) as sp_auf_m2_7,
max(case when p.spr_nr = 80 then p.sp_auf_m2 end) as sp_auf_m2_80,
max(case when p.spr_nr = 235 then p.sp_auf_m2 end) as sp_auf_m2_235
from
kust k
inner join
kust_adr ka
on k.kunr = ka.ku_nr
left outer join
sp_przu p
on k.kunr = p.kunr
and p.prl_nr = 2
and p.spr_nr in (1, 4, 6, 189, 191, 7, 80, 235)
where
ka.ku_adr_art = 0
group by
ltrim(k.kunr),
ka.ku_name
order by
kunr;
Комментарии:
1. Спасибо! Сначала работает по мере необходимости, спасибо. Второй намного аккуратнее, но не запускается с моей стороны. Я не вижу, где синтаксическая ошибка, хотя:/ ОШИБКА в строке 21: ORA-00933: команда SQL не завершена должным образом
2. Возможно, вы используете старую версию; pivot не добавлялся до 11g. Вы можете сделать то же самое с выражениями регистра, хотя, если хотите.
3. Ах, это было бы так, это 10g 🙁
4. @user316478 — Я добавил эквивалент 10g * 😎
5. Спасибо, как ни странно, я получаю 835 строк, используя первую, и 784 строки, используя третью… В идеале третий был бы правильным, поскольку у меня есть еще много идентификаторов продукта, которые нужно добавить в микс, и это проще сделать… 😀