简体   繁体   中英

ora-01427 single-row subquery returns error in select statement

I have a data set as follows:

ID  keyword1
1   abc
2   abc1
1   xyz
3   hjh
3   pou

I want the output as follows:

ID  keyword1  keyword2
1   abc       xyz
2   abc1
3   hjh       pou

the condition is: if there are more than 1 rows for a particular ID, then i should get another column of keyword in the same ID row. If no matching rows, then it should be null.

i am using the below query:

select c.ID,
    (select KEYWORD from table1 a where a.ECF_RULE_ID=c.ECF_RULE_ID) as  KEYWORD1,
    (select KEYWORD from table2 b where b.ECF_RULE_ID=c.ECF_RULE_ID) as KEYWORD2
from table3 c

but i am getting the error as:

ORA-01427: single-row subquery returns more than one row.

Please help.

Looks you need something like;

select
c.ID,
a.keyword as KEYWORD1,
b.keyword as KEYWORD2

from
table3 c
LEFT JOIN table1 a ON a.ECF_RULE_ID=c.ECF_RULE_ID
LEFT JOIN table2 b ON b.ECF_RULE_ID=c.ECF_RULE_ID

Please look into joins, it's very powerfull.

If you have more than 2 value by ID, may be you can try another way, using "analytic windows function" like rank

select
    ECF_RULE_ID as ID,
    KEYWORD,
    rank() over (partition by ECF_RULE_ID order by KEYWORD ) as POSITION
from
    table1

result :

ID  KEYWORD  POSITION
1   abc      1
1   xyz      2
2   abc1     1
3   hjh      1
3   pou      2

I think you are trying to use correlated query to return your desired result which can be obtained as below.

SELECT id
    ,keyword1
    ,CASE 
        WHEN keyword2 <> keyword1
            THEN keyword2
        ELSE NULL
        END AS keyword2
FROM (
    SELECT DISTINCT c.id
        ,(
            SELECT min(keyword)
            FROM t1 a
            WHERE a.ID = c.ID
            ) AS Keyword1
        ,(
            SELECT max(keyword)
            FROM t1 b
            WHERE b.ID = c.ID
            ) AS Keyword2
    FROM t1 c
    ) t
order by id;

what the above query does is that the inner correlated queries return corresponding min and max values in separate columns, distinct remove duplicates and case forces keyword2 values to NULL if it matches keyword1 values.

Result:

id  keyword1    keyword2
------------------------
1   abc         xyz
2   abc1        
3   hjh         pou

You can check the demo here


Update 1:

You can also use left join as below to obtain your desired result.

SELECT id
    ,keyword1
    ,CASE 
        WHEN keyword2 <> keyword1
            THEN keyword2
        ELSE NULL
        END AS keyword2
FROM (
    SELECT a.id
        ,max(a.keyword) AS keyword1
        ,min(b.keyword) AS keyword2
    FROM t1 a
    LEFT JOIN t1 b ON a.id = b.id
    GROUP BY a.id
    ) t
ORDER BY id;

Result:

id  keyword1    keyword2
------------------------
1   abc         xyz
2   abc1        
3   hjh         pou

DEMO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM