Reputation: 1336
I'm using Oracle 11g R2.
I want to return a single value from a table which has multiple child rows. The subquery must return the value based on the max number of values of a second unrelated column.
The following code provides data in form of CTEs... and a failed attempt to create the statement. I know I have to differentiate somehow the values so that it returns the one that has the max number of child.
Check on the snippet "Expected result".
WITH GRPS(GRP, SUBGRP)
AS
(
SELECT 'AAA', 'SUB_A1' FROM DUAL UNION ALL
SELECT 'AAA', 'SUB_A2' FROM DUAL UNION ALL
SELECT 'AAA', 'SUB_A2' FROM DUAL UNION ALL
SELECT 'AAA', 'SUB_A2' FROM DUAL UNION ALL
SELECT 'AAA', 'SUB_A3' FROM DUAL UNION ALL
SELECT 'BBB', 'SUB_B5' FROM DUAL UNION ALL
SELECT 'BBB', 'SUB_B6' FROM DUAL UNION ALL
SELECT 'BBB', 'SUB_B6' FROM DUAL UNION ALL
SELECT 'BBB', 'SUB_B7' FROM DUAL
),
TAB1 (GRP)
AS
(
SELECT 'AAA' FROM DUAL UNION ALL
SELECT 'BBB' FROM DUAL
)
(
SELECT
TAB1.GRP,
GRPS.SUBGRP,
COUNT(*)
FROM TAB1
JOIN GRPS
ON (GRPS.GRP = TAB1.GRP)
GROUP BY TAB1.GRP,
GRPS.SUBGRP
-- That will get me these:
-- Row# GRP SUBGRP COUNT(*)
-- 1 BBB SUB_B5 1
-- 2 AAA SUB_A2 3
-- 3 AAA SUB_A1 1
-- 4 BBB SUB_B6 2
-- From which I still have to perform a search to get me the rows with SUB_B6 AND SUB_A2
-- Expected result
-- AAA SUB_A2
-- BBB SUB_B6
)
;
This, of course, will not work and get me an error like "single-row subquery returns more than one row". I dont' need to get just any row from the correlated subquery. I need to get the value from which there are more repeated from that table. In this case SUB_A2, AND SUB_B6.
Upvotes: 0
Views: 62
Reputation: 93694
Use Analytic Function
. Try this
WITH GRPS(GRP, SUBGRP)
AS
(
SELECT 'AAA', 'SUB_A1' FROM DUAL UNION ALL
SELECT 'AAA', 'SUB_A2' FROM DUAL UNION ALL
SELECT 'AAA', 'SUB_A2' FROM DUAL UNION ALL
SELECT 'AAA', 'SUB_A2' FROM DUAL UNION ALL
SELECT 'BBB', 'SUB_B5' FROM DUAL UNION ALL
SELECT 'BBB', 'SUB_B6' FROM DUAL UNION ALL
SELECT 'BBB', 'SUB_B6' FROM DUAL
),
TAB1 (GRP)
AS
(
SELECT 'AAA' FROM DUAL UNION ALL
SELECT 'BBB' FROM DUAL
)
(
select grp,subgrp from(
SELECT
TAB1.GRP,
GRPS.SUBGRP,
row_number() over(partition by TAB1.GRP order by count(1) desc) rn
FROM TAB1
JOIN GRPS
ON (GRPS.GRP = TAB1.GRP)
group by TAB1.GRP,
GRPS.SUBGRP
) a where rn=1
)
;
Upvotes: 1