Home » SQL & PL/SQL » SQL & PL/SQL » SubQuery Problem (Oracle SQL Developer 3.1.07)
SubQuery Problem [message #618831] |
Wed, 16 July 2014 00:19 |
|
HeyMoe
Messages: 9 Registered: July 2014 Location: Australia
|
Junior Member |
|
|
I'm trying to do a subquery (bold section) but it keeps returning "single-row subquery returns more than one row" everytime it's run. I'm using Oracle SQL Developer 3.1.07. Oracle version 12 I believe. Not 100% sure! Sorry )
Basically it's suppose to check the SUB_GRP_TO_NAME table for a SUB_GRP_NAME that matches that which is in AC_LOAD, and populate the associated SPID_NAME into GTT_AC_NORMAL. If there is no SUB_GRP_NAME match, then SPID_NAME in GTT_AC_NORMAL is set to 'Unknown'. If the value of SUB_GRP_NAME in AC_LOAD is NULL, then it's set to 9999.
It all works except for the sub query bit!
Any help would be appreciated.
Thanks.
(Hope I got everything right)
Here it is!
PROCEDURE DO_NORMALISE (p_batch_date IN DATE)
IS
v_partkey number := to_number(to_char(p_batch_date,'YYYYMMDD'));
BEGIN
INSERT into GTT_AC_NORMAL( SUB_GRP_NAME, SPID_NAME,MSG_ID, SUCCESS_COUNT, FAIL_COUNT, VISITED_MCC)
(select
SUB_GRP_NAME,
(select
NVL (SUB_GRP_TO_NAME.SPID_NAME, 'Unknown SPID')
from AC_LOAD
inner join SUB_GRP_TO_NAME
on (SUB_GRP_TO_NAME.SUB_GRP_NAME = NVL(AC_LOAD.SUB_GRP_NAME, '9999') )
)SPID_NAME,
AL.MSG_ID,
case when (AL.SEND_STATUS = '1') then 1
when (AL.SEND_STATUS = '0') then 0
end SUCCESS_COUNT,
case when (AL.SEND_STATUS = '1') then 0
when (AL.SEND_STATUS = '0') then 1
end FAIL_COUNT,
MC1.MCC_NAME as VISITED_MCC
from AC_LOAD AL,
MCC_TO_NAME MC1
where (SEND_STATUS is not null
and PARTKEY = V_PARTKEY
and BATCH_DATE = P_BATCH_DATE
and AL.VISITED_MCC = MC1.MCC
) and MSG_ID <> 'Warning'
);
END;
Table examples:
AC_LOAD
PARTKEY BATCH_DATE SUB_GRP_NAME SEND_STATUS MSG_ID VISITED_MCC
20140704 04/JUL/14 01:45:00 0156 0 pp_msg1 91
20140704 04/JUL/14 01:45:00 0123 1 mp_msg2 125
20140704 04/JUL/14 01:45:00 (null) 0 ep_msg1 36
20140704 04/JUL/14 01:45:00 2121 1 pp_msg2 47
SUB_GRP_TO_NAME
SUB_GRP_NAME SPID_NAME
0156 Bobby
0123 Barry
9999 Older
What I would like to see in GTT_AC__NORMAL
PARTKEY BATCH_DATE SUB_GRP_NAME SEND_STATUS MSG_ID VISITED_MCC
20140704 04/JUL/14 01:45:00 Bobby 0 pp_msg1 New York
20140704 04/JUL/14 01:45:00 Barry 1 mp_msg2 Boston
20140704 04/JUL/14 01:45:00 Older 0 ep_msg1 Paris
20140704 04/JUL/14 01:45:00 Unknown 1 pp_msg2 Melbourne
(I haven't included the table MCC_TO_NAME because it works.)
Thanks.
[Updated on: Wed, 16 July 2014 00:47] Report message to a moderator
|
|
|
Re: SubQuery Problem [message #618836 is a reply to message #618831] |
Wed, 16 July 2014 01:23 |
|
Michel Cadot
Messages: 68647 Registered: March 2007 Location: Nanterre, France, http://...
|
Senior Member Account Moderator |
|
|
Never use suhquery in SELECT clause until you''l be an expert in SQL.
Use an outer join in FROM clause instead.
Your analyze of what does this subquery is wrong.
Quote: If there is no SUB_GRP_NAME match, then SPID_NAME in GTT_AC_NORMAL is set to 'Unknown'.
No, as you use an inner join, if there is no match you have no rows and, as this is a subquery in SELECT clause you have a NULL.
Once again, transfer this subquery to the FROM clause and use an OUTER JOIN.
Quote:If the value of SUB_GRP_NAME in AC_LOAD is NULL, then it's set to 9999.
No it is not set to this, if "set" means one of the inserted value:
"INSERT into GTT_AC_NORMAL( SUB_GRP_NAME, ... select SUB_GRP_NAME,..."
|
|
|
|
Re: SubQuery Problem [message #618840 is a reply to message #618838] |
Wed, 16 July 2014 01:52 |
|
Michel Cadot
Messages: 68647 Registered: March 2007 Location: Nanterre, France, http://...
|
Senior Member Account Moderator |
|
|
Quote:If I have a NULL, doesn't this "NVL (SUB_GRP_TO_NAME.SPID_NAME, 'Unknown SPID')" substitute 'Unknown SPID' in this case?
Yes, it means that... if you have a row, but if you have no match than there is no row, so no value to apply NVL on:
SQL> select nvl(null,'Michel') val from dual where 1=1;
VAL
------
Michel
1 row selected.
SQL> select nvl(null,'Michel') val from dual where 1=2;
no rows selected
|
|
|
|
Re: SubQuery Problem [message #618957 is a reply to message #618841] |
Wed, 16 July 2014 19:49 |
|
HeyMoe
Messages: 9 Registered: July 2014 Location: Australia
|
Junior Member |
|
|
Thanks Michel. Your help is very appreciated.I am now not getting the "single-row subquery returns more than one row" error anymore.
It now seems to runs OK....but
with my code now looking like this, the WHERE clause doesn't seem to get used?
from AC_LOAD AL,
MCC_TO_NAME MC1,
SUB_GRP_TO_NAME
outer join AC_LOAD
on (SUB_GRP_TO_NAME.SUB_GRP_NAME = NVL(AC_LOAD.SUB_GRP_NAME, '9999'))
where AL.SEND_STATUS is not null
and AL.PARTKEY = V_PARTKEY
and AL.BATCH_DATE = P_BATCH_DATE
and AL.VISITED_MCC = MC1.MCC
and AL.MSG_ID <> 'Wholesale_Warning'
)
[Updated on: Wed, 16 July 2014 20:20] Report message to a moderator
|
|
|
Re: SubQuery Problem [message #618975 is a reply to message #618957] |
Thu, 17 July 2014 01:28 |
flyboy
Messages: 1903 Registered: November 2006
|
Senior Member |
|
|
HeyMoe wrote on Thu, 17 July 2014 02:49Thanks Michel. Your help is very appreciated.I am now not getting the "single-row subquery returns more than one row" error anymore.
It now seems to runs OK....but
with my code now looking like this, the WHERE clause doesn't seem to get used?
I would disagree, it is used, but, as you are cross joining AC_LOAD table with itself, you are filtering only one of its occurences.
Of course this was also the functionality of your original query too. You could reveal it by simply running the subquery alone and examining its results. Note, that that result was assigned to every row to the outer SELECT - and failed as it was supposed to return (at most) one row.
The new query has exactly the same problem - why are you joining AC_LOAD table twice? One occurrence in FROM clause would be enough.
And, while you will rewrite the query, stop combining "old" joins (,) with ANSI ones (INNER/OUTER/FULL JOIN) in one FROM clause. You should choose only one of them there.
|
|
|
Re: SubQuery Problem [message #619075 is a reply to message #618975] |
Thu, 17 July 2014 19:46 |
|
HeyMoe
Messages: 9 Registered: July 2014 Location: Australia
|
Junior Member |
|
|
flyboy wrote on Thu, 17 July 2014 16:28I would disagree, it is used, but, as you are cross joining AC_LOAD table with itself, you are filtering only one of its occurences.
Of course this was also the functionality of your original query too. You could reveal it by simply running the subquery alone and examining its results. Note, that that result was assigned to every row to the outer SELECT - and failed as it was supposed to return (at most) one row.
The new query has exactly the same problem - why are you joining AC_LOAD table twice? One occurrence in FROM clause would be enough.
And, while you will rewrite the query, stop combining "old" joins (,) with ANSI ones (INNER/OUTER/FULL JOIN) in one FROM clause. You should choose only one of them there.
I thought I was joining AC_LOAD with SUB_GRP_TO_NAME.
SUB_GRP_TO_NAME
outer join AC_LOAD
When I modified it to this, I receive this error:
"Error(168,40): PL/SQL: ORA-00904: "AC_LOAD"."SUB_GRP_NAME": invalid identifier.
from
MCC_TO_NAME MC1,
SUB_GRP_TO_NAME
right inner join AC_LOAD
on (SUB_GRP_TO_NAME.SUB_GRP_NAME = NVL(AC_LOAD.SUB_GRP_NAME, '9999') )
|
|
|
|
Re: SubQuery Problem [message #619077 is a reply to message #619076] |
Thu, 17 July 2014 20:28 |
|
HeyMoe
Messages: 9 Registered: July 2014 Location: Australia
|
Junior Member |
|
|
Why are CREATE TABLE statements so important?
These are pre-created tables that have data fed into them from an external source.
The table GTT_AC__NORMAL is also already created. It's there waiting.
The data is as per my original post.
I really have nothing else to show.
[EDITED by LF: removed unnecessary quote of the whole previous message]
[Updated on: Fri, 18 July 2014 05:36] by Moderator Report message to a moderator
|
|
|
Re: SubQuery Problem [message #619086 is a reply to message #619077] |
Fri, 18 July 2014 00:30 |
Lalit Kumar B
Messages: 3174 Registered: May 2013 Location: World Wide on the Web
|
Senior Member |
|
|
HeyMoe wrote on Fri, 18 July 2014 06:58
Why are CREATE TABLE statements so important?
So that anybody could replicate your issue. A working test case is very useful to recreate your problem. Nobody can be 100% correct with their suggestion just by gazing at an error code or a part of a code.
|
|
|
Re: SubQuery Problem [message #619096 is a reply to message #619086] |
Fri, 18 July 2014 00:57 |
|
HeyMoe
Messages: 9 Registered: July 2014 Location: Australia
|
Junior Member |
|
|
I thought that snippets of the actual data would be OK.
I didn't create these tables, they're just there. I don't even control when the data appears. I just run the SQL file from
a Oracle SQL Developer 'SQL Worksheet'.
Thanks,
[EDITED by LF: removed unnecessary quote of the whole previous message]
[Updated on: Fri, 18 July 2014 05:37] by Moderator Report message to a moderator
|
|
|
|
Re: SubQuery Problem [message #619382 is a reply to message #619077] |
Tue, 22 July 2014 02:17 |
flyboy
Messages: 1903 Registered: November 2006
|
Senior Member |
|
|
Maybe too late (as I was on vacancies), anyway...
HeyMoe wrote on Fri, 18 July 2014 03:28Why are CREATE TABLE statements so important?
These are pre-created tables that have data fed into them from an external source.
People here tend to give precise answers, however they are limited to the detailness of questions. As you gave only syntactically incorrect queries/snippets (see below) and one error message, BlackSwan's answer is the best one, as the error message you posted is very clean - table/view/whatever else named "AC_LOAD" does not have column named "SUB_GRP_NAME".
Plus, people here are pleased by the feedback from you. Additionally it helps future readers when facing the similar problem. If they do not receive it, they suppose you do not care about their answers, so they find no reason for answering your future questions. As you ignored my suggestion about mixing join types, I am starting to suppose the same.
I was puzzled by your use of ANSI join keyword mix, as both ones are invalid.
SQL> select * from dual d1 outer join dual d2 on d1.dummy = d2.dummy;
select * from dual d1 outer join dual d2 on d1.dummy = d2.dummy
*
ERROR at line 1:
ORA-00933: SQL command not properly ended
SQL> select * from dual d1 right inner join dual d2 on d1.dummy = d2.dummy;
select * from dual d1 right inner join dual d2 on d1.dummy = d2.dummy
*
ERROR at line 1:
ORA-00905: missing keyword
Did you just guess it? Of course, you can find its correct use on many internet sites (as it is ANSI standard). For Oracle, it is placed in SQL Language Reference book, which is available with other Oracle documentation e.g. online on http://docs.oracle.com/ Just search for SELECT statement.
HeyMoe wrote on Fri, 18 July 2014 03:28The data is as per my original post.
According to the error message you posted, it is not. However nobody is able to (dis)prove it as they do not have access to the mentioned tables.
Good luck.
|
|
|
Goto Forum:
Current Time: Fri Apr 26 19:40:54 CDT 2024
|