Список Oracle с CASE

avatar
Arty155
8 августа 2021 в 21:00
47
1
1

У меня есть 2 таблицы, которые объединены в order_item_xm.par_rowid = order_item.oi_rowid:

create table order_item_xm (oix_rowid varchar2(10),
                            par_rowid varchar2(10),
                            type      varchar2(30),
                            name      varchar2(30) );
                  
create table order_item (oi_rowid       varchar2(10) );
                         
insert into order_item_xm values ('3-AUXHJ', '3-BHUYI', 'ATS', '2-ATS0J');
insert into order_item_xm values ('3-AUXHK', '3-BHUYI', 'CART', 'a4beecj02kl');
insert into order_item_xm values ('3-AUXBW', '3-AKTKZ', 'ATS', 'SA-92');
insert into order_item_xm values ('3-AUXCY', '3-AKTKZ', 'CART', 'b3kl-hg7tcrd');
insert into order_item_xm values ('3-AUXMN', '3-AKTKZ', 'CART', 'n9-vgnj78lsd');
insert into order_item_xm values ('3-CKITY', '3-KB8UI', 'ATS', '2-ATS8U');
insert into order_item_xm values ('3-CMITY', '3-KB8UI', 'HES', 'HES09');
insert into order_item_xm values ('3-CZUIO', '3-KB8UI', 'HES', 'HES04');
insert into order_item_xm values ('3-CZAST', '3-KB8UI', 'ATS', '2-ATS6R');

insert into order_item(oi_rowid) values ('3-BHUYI');
insert into order_item(oi_rowid) values ('3-AKTKZ');
insert into order_item(oi_rowid) values ('3-KB8UI');

Я хочу соединить 2 таблицы и получить псевдостолбец с именем "идентификатор корзины", когда столбец с именем type в таблице order_item_xm имеет значение CART. Если значение не CART, то должна отображаться строка «Идентификатор корзины не найден».

Ниже мой запрос:

select a.oi_rowid, b.type, listagg(case b.type
                                      WHEN 'CART' THEN b.name
                                      ELSE 'No cart id found'
                                    end, ',') within group(order by b.name) as cart_id
from order_item a INNER JOIN order_item_xm b ON (a.oi_rowid = b.PAR_ROWID) group by a.oi_rowid, b.type;

Вывод:

enter image description here

Вот моя проблема 1: В значении oi_rowid 3-KB8UI нет значения CART в типе столбца, но из-за listagg дважды появляется строка «Идентификатор корзины не найден». В любом случае, чтобы этого не делать - в основном не объединяйте значения столбца TYPE, когда значение CART отсутствует.

2nd: для значения oi_rowid 3-BHUYI значение a4beecj02kl для cart_id также должно отображаться для ATS. То же самое касается значения oi_rowid для 3-AKTKZ — значение «b3kl-hg7tcrd,n9-vgnj78lsd» для cart_id также должно отображаться для ATS.

Ожидаемый результат:

enter image description here

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

РЕДАКТИРОВАТЬ: Извините, я обновил ожидаемый результат. Предыдущий был ошибкой. Это правильный вариант.

Источник

Ответы (1)

avatar
sticky bit
8 августа 2021 в 21:11
1

Выполните CASE после агрегирования, вы все равно получите type там.

SELECT a.oi_rowid,
       b.type,
       CASE b.type
         WHEN 'CART' THEN
           listagg(b.name, ',') WITHIN GROUP (ORDER BY b.name)
         ELSE
           'No cart id found'
       END cart_id
       FROM order_item a
            INNER JOIN order_item_xm b
                       ON a.oi_rowid = b.par_rowid
       GROUP BY a.oi_rowid,
                b.type;

дб<>скрипка


Изменить:

Чтобы имитировать оконную и фильтрованную версию listagg() -- насколько я могу судить, нет встроенной версии, допускающей фильтры -- можно использовать коррелированные подзапросы.

WITH cte
AS
(
SELECT a.oi_rowid,
       b.type,
       b.name
       FROM order_item a
            INNER JOIN order_item_xm b
                       ON a.oi_rowid = b.par_rowid
)
SELECT co.oi_rowid,
       co.type,
       CASE
         WHEN EXISTS (SELECT *
                             FROM cte ci
                             WHERE ci.oi_rowid = co.oi_rowid
                                   AND ci.type = 'CART') THEN
           (SELECT listagg(ci.name, ',') WITHIN GROUP (ORDER BY ci.name)
                   FROM cte ci
                   WHERE ci.oi_rowid = co.oi_rowid
                         AND ci.type = 'CART')
         ELSE
           'No cart id found'
       END cart_id
       FROM cte co
       ORDER BY co.oi_rowid,
                co.type;

дб<>скрипка

Arty155
8 августа 2021 в 21:25
0

Извините, я обновил ожидаемый результат. Приношу извинения за неправильный ожидаемый результат.

Arty155
8 августа 2021 в 22:25
0

Спасибо! Это сработало. Да, Вы правы, в листагге нет родного фильтра. Я пытался придумать решение, используя аналитические функции, такие как first_value/last_value, но не смог его придумать. Хотя это определенно работает! И спасибо за столь быстрый ответ.