53

Is there any easy way to return single scalar or default value if query doesn't return any row?

At this moment I have something like this code example:

IF (EXISTS (SELECT * FROM Users WHERE Id = @UserId))  
    SELECT Name FROM Users WHERE Id = @UserId  
ELSE
    --default value
    SELECT 'John Doe'

How to do that in better way without using IF-ELSE?

1
  • create a stored procedure for any database programming with additional logic. Commented Jul 22, 2012 at 23:00

8 Answers 8

89

Assuming the name is not nullable and that Id is unique so can match at most one row.

 SELECT 
    ISNULL(MAX(Name),'John Doe')
 FROM 
    Users 
 WHERE 
    Id = @UserId  
Sign up to request clarification or add additional context in comments.

6 Comments

Simplest version so far and +1 on mentioning the unique requirement.
@ChrisGessler - Yes. A MAX without a GROUP BY or HAVING always returns one row.
SWEET! +1 for you. Nice trick, I'll have to remember this. I already know of several spots I can use it.
Good solution but the MAX filter is unnecessary as you've already established the data is unique with the WHERE clause. The MAX will also error (at least with MSSQL) if your table only stores unique entries and you don't need to use a WHERE or GROUP BY clause to establish uniqueness.
@azariah the MAX is required to turn zero rows into 1 rows in the case the value does not exist. Seems strange that MySql would error as the SQL is perfectly valid but the Q is for Microsoft Sql Server anyway
|
31

Try ISNULL or COALESCE:

SELECT ISNULL((SELECT TOP 1 Name FROM Users WHERE Id = @UserId), 'John Doe')

The inner select will return nothing if no user exist with this id, the isnull will solve this case.

4 Comments

+1 but there's a small risk that the select returns more than one row in wich case this won't work.
Sweet little one liner, but you'll need to add top 1 (just in case)
I am not sure if having a subquery will decrease performance if used at a larger scale (compared to the solution by Martin Smith), but I like how intuitive your solution is.
8

Try this:

SELECT ISNULL(Name, 'John Doe')
FROM Users
WHERE (Id = @UserId)

2 Comments

You made a typo : ISNULL.
I have answered it around 2017 may be it has been removed in the later version. Feel free to modify @MaximeBaker
4

You can drop the if statement using following construct but that doesn't necessarely mean it is better.

SELECT Name FROM Users WHERE Id = @UserId UNION ALL 
SELECT 'John Doe' WHERE NOT EXISTS (SELECT Name FROM Users WHERE  Id = @UserId)

Comments

3

Try isnull

SELECT IsNULL(Name, 'John Doe')  FROM Users WHERE Id = @UserId

Edit:

drop table users
go
create table users
(id int,name varchar(20))
go
insert into users select 1,'1'
 go
declare @userid int
set @userid = 1
select isnull(username.username, 'John Doe')
from (select @userid as userid) userid
outer apply (SELECT  name as username FROM Users WHERE Id = userid.userid ) username
--outer apply (SELECT  name as username FROM Users WHERE Id = @userid ) username

4 Comments

This requires at least 1 record with a null value for Name
select isnull(username.username,'your vaklue') as username from (select null userid) a outer apply ( select username from usertable where userid = a.userid) username
Update your answer, I hadn't though of outer apply.
Worked beautifully! Good one!
2

I suppose you could use @@ROWCOUNT to see if any will be returned.

SELECT Name FROM Users WHERE Id = @UserId  
if(@@ROWCOUNT = 0)
  SELECT 'John Doe'

You could also use a variable if you're expecting one row.

declare @name varchar(100)
set @name = (select top 1 name from users where id = @userId)
if(@name is null) set @name = 'John Doe'
select @name

Comments

2

I would suggest that the best way to do is that first declare @name . Then set this value based on user id and then if @name is null show default name otherwise show name... That method would be as efficient as any other method and will be more readable.for other methods any other user to have think a lot to know what is going on unless there is nice comment.

declare @userid int
set @userid = 1
select isnull(
               (select name from users where id = @userid),
               'John Doe'
               )
 go
--My preffered would be this one..
declare @name varchar(20),@userid int
set @userid = 1
select  @name =  name from users where id = @userid
select isnull(@name,'John Doe') 

Comments

1

If the query is supposed to return at most one row, use a union with the default value then a limit:

SELECT * FROM 
 (
  SELECT Name FROM Users WHERE Id = @UserId`
  UNION
  SELECT 'John Doe' AS Name --Default value
 ) AS subquery
LIMIT 1

Both the query and default can have as many columns as you wish, and you do not need to guarantee they are not null.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.