31 May 2006 17:38 tonyrogerson

Subquery returned more than 1 value

I've had so many referrals from google on this error because of my previous blog entry on the T-SQL Value assignment SET vs SELECT I've decided to expand into this specific error and in what situations you get it, what causes it and how to get round it.

Msg 512, Level 16, State 1, Line 12

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

Some test data...

create table #test (
   mypk int not
null,
   fullname varchar(100) not
null
)

insert #test ( mypk, fullname ) values( 1, 'Tony Rogerson' )
insert #test ( mypk, fullname ) values( 2, 'Tony Rogerson'
)
insert #test ( mypk, fullname ) values( 3, 'Simon Sabin'
)
insert #test ( mypk, fullname ) values( 4, 'Trevor Dwyer'
)

The error message is pretty self-explanatory once you remember what a subquery is. A subquery is a query within your main query, for example the query below reproduces the behaviour and gives the message...

select *
from
#test
where mypk = ( select
mypk
               from
#test
               where fullname = 'Tony Rogerson' )

The sub-query is the bit between the braces, the sub-query in itself is fine and valid, its because we are using an operator that expects comparison against a constant rather than a set. Our sub-query is returning 2 rows and because we are using '=' equals expects a single value (1 row, 1 column).

The correct thing to do depends on your problem, we can do a number of things we can change the single value operator to an operator that can deal with sets, so we change from '=' to 'IN' and now everything works fine.

select *
from
#test
where mypk IN ( select
mypk
                from
#test
                where fullname = 'Tony Rogerson' )

This might not be what you want, the above query has changed in behaviour because it can now return multiple mypk, so if you where expecting a look up on a single mypk then you are stuffed. We can get round that by using the TOP keyword, however, think about what you are doing - it may not be valid, what determines which mypk gets selected? As the query below demonstrates we can get a random mypk, its going to be either 1 or 2.

select *
from
#test
where mypk = ( select
TOP 1 mypk
               from
#test
               where fullname = 'Tony Rogerson' )

When using TOP in a sub-query you can also use ORDER BY, this is the only time you can use ORDER BY in a sub-query, to digress, people started to use an undocumented behaviour where you can order a view but SQL 2005 now breaks that behaviour so my message is clear never use ORDER BY and TOP in a view and expect the view to be ordered - it won't be!!

select *
from
#test
where mypk = ( select
TOP 1 mypk
               from
#test
               where fullname = 'Tony Rogerson'
               order by mypk DESC
)

Again using this solution depends on the business requirement you are trying to resolve.

Sub-queries can exist in many places, on the SELECT clause, in a CASE statement in many of the builtin functions like DATEDIFF.

I think my only advice if you get this is to check that your using keys correctly, I'm a very pro on using surrogate keys so make sure you never get into this situation in the first place.

Remember =, !=, <, <= , >, >= all expect single values (0 or 1 row, 1 column), EXISTS and IN are set operators and as such expect a set of data (0 or more rows).

Tony.

 

Filed under:

Comments

# re: Subquery returned more than 1 value

01 June 2006 10:06 by Colin Leversuch-Roberts

I'm still amazed that after so many years this still causes problems, If I wasn't too old I'd say I was a definite grumpy old DBA !! , when I look at the forums and such I sometimes dispair at the questions - although it probably explains the appalling quality of many of the applications I encounter .. told you I was getting grumpy !!  In fact I consider this so basic I didn't even think of placing it in my best practices documentation ( and upcoming presentation ) Maybe I should do a last minute addition?

# re: Subquery returned more than 1 value

01 June 2006 12:09 by tonyrogerson

Absolutely Colin, I was gob smacked by the number of referals from people searching on this error so it is very common. Put it in your presentation and see you Saturday :).

# re: Subquery returned more than 1 value

01 June 2006 12:30 by Colin Leversuch-Roberts

OK will do ..  My doc is based ( and presentation from ) largely on those things I encountered which were/are troublesome when handling software releases in controlled environments ( so no ad-hoc changes to scripts allowed ) plus solutions / fixes / workarounds to problems in applications. When I look at it it's a strange mixture to be sure! I never suffered too much from the dreaded subquery problem .. perhaps I was lucky.