Oracle Join не возвращает данные, если 1 столбец пуст

#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 строки, используя третью… В идеале третий был бы правильным, поскольку у меня есть еще много идентификаторов продукта, которые нужно добавить в микс, и это проще сделать… 😀