Reputation: 113
I have 2 tables which are joined on 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');
I want to join the 2 tables and get a pseudo column named "cart id" when column named type in table order_item_xm has value of CART. If the value is not CART then string "No Cart ID found" should be displayed.
Below is my query :
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;
And the output is :
Here is my problem 1: In the oi_rowid value 3-KB8UI there is no value CART in column type but because of listagg the string "No Cart ID found" appears twice. Is there anyway to not do that - basically do not concatenate values of column TYPE when the value CART is not present.
2nd : For oi_rowid value of 3-BHUYI value a4beecj02kl for cart_id should appear for ATS too. Same goes for oi_rowid value of 3-AKTKZ - value "b3kl-hg7tcrd,n9-vgnj78lsd" for cart_id should appear for ATS too.
Expected output is :
Can someone please help with this query?
EDIT : Sorry I updated the expected output. The previous one was a mistake. This is the correct one.
Upvotes: 1
Views: 158
Reputation: 37472
Do the CASE
after the aggregation, you still got the type
there.
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;
Edit:
To simulate a windowed and filtered version of listagg()
-- as far as I can tell, there is no native one that allows for filters -- you can use correlated subqueries.
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;
Upvotes: 1