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 Go to next message
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 Sad )

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 Go to previous messageGo to next message
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 #618838 is a reply to message #618836] Wed, 16 July 2014 01:34 Go to previous messageGo to next message
HeyMoe
Messages: 9
Registered: July 2014
Location: Australia
Junior Member
Michel Cadot wrote on Wed, 16 July 2014 16:23

Never use suhquery in SELECT clause until you''l be an expert in SQL.
Use an outer join in FROM clause instead.

Do you mean use the last FROM clause?

Michel Cadot wrote on Wed, 16 July 2014 16:23

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.

If I have a NULL, doesn't this "NVL (SUB_GRP_TO_NAME.SPID_NAME, 'Unknown SPID')" substitute 'Unknown SPID' in this case?

Thanks for your comments.
Re: SubQuery Problem [message #618840 is a reply to message #618838] Wed, 16 July 2014 01:52 Go to previous messageGo to next message
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 #618841 is a reply to message #618838] Wed, 16 July 2014 01:53 Go to previous messageGo to next message
Michel Cadot
Messages: 68647
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Quote:
Do you mean use the last FROM clause?


I mean the FROM clause that is part of the SELECT where the subquery is.

Re: SubQuery Problem [message #618957 is a reply to message #618841] Wed, 16 July 2014 19:49 Go to previous messageGo to next message
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 Go to previous messageGo to next message
flyboy
Messages: 1903
Registered: November 2006
Senior Member
HeyMoe wrote on Thu, 17 July 2014 02:49
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?

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 Go to previous messageGo to next message
HeyMoe
Messages: 9
Registered: July 2014
Location: Australia
Junior Member
flyboy wrote on Thu, 17 July 2014 16:28
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.


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 #619076 is a reply to message #619075] Thu, 17 July 2014 20:08 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
We don't have your tables.
We don't have your data.

>"Error(168,40): PL/SQL: ORA-00904: "AC_LOAD"."SUB_GRP_NAME": invalid identifier.
Oracle is too dumb to lie about what is wrong.
above indicates that this error occurred on line#168

post CREATE TABLE statement for AC_LOAD table.

why do you NEVER post whole SQL statements; only code fragments?

How will you, I or anyone recognize when correct solution is posted?
Re: SubQuery Problem [message #619077 is a reply to message #619076] Thu, 17 July 2014 20:28 Go to previous messageGo to next message
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 Go to previous messageGo to next message
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 Go to previous messageGo to next message
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 #619100 is a reply to message #619096] Fri, 18 July 2014 01:07 Go to previous messageGo to next message
Michel Cadot
Messages: 68647
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

So post this file.
To clarify what has been posted, we need the table to execute the query and fix and improve it.

Re: SubQuery Problem [message #619382 is a reply to message #619077] Tue, 22 July 2014 02:17 Go to previous message
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:28
Why 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:28
The 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.
Previous Topic: use between in case on one fild
Next Topic: SQL
Goto Forum:
  


Current Time: Fri Apr 26 19:40:54 CDT 2024