2012-07-16 13 views
33

Czy istnieje prosty sposób na zwrócenie pojedynczej wartości skalarnej lub wartości domyślnej, jeśli zapytanie nie zwraca żadnego wiersza?Jak przywrócić wartość domyślną z zapytania SQL

W tej chwili mam coś takiego przykładu kodu:

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

jak to zrobić w lepszy sposób bez użycia if-else?

+0

utworzyć procedurę przechowywaną w dowolnym programowania baz danych z dodatkową logikę. –

Odpowiedz

59

Zakładając, że nazwa nie jest pustych i Id jest wyjątkowy więc może się równać co najwyżej jednym rzędzie.

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

Najprostsza do tej pory wersja i +1 przy wymienieniu unikalnego wymagania. –

+1

Czy to działa, gdy nie są zwracane żadne wiersze? –

+3

@ChrisGessler - Tak. 'MAX' bez' GROUP BY' lub 'HAVING' zawsze zwraca jeden wiersz. –

21

Spróbuj ISNULL lub COALESCE:

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

Wewnętrzna select zwróci nic, jeśli użytkownik nie istnieje z tego identyfikatora, IsNull rozwiąże tę sprawę.

+0

+1, ale istnieje niewielkie ryzyko, że select zwróci więcej niż jeden wiersz, w którym to przypadku nie zadziała. –

+6

Nie używaj 'COALESCE' jako [to będzie dwukrotnie oceniać pod-zapytanie] (http://connect.microsoft.com/SQLServer/feedback/details/336002/niepotrzebnie-bad-performance-for-coalesce-subquery) –

+0

Słodka mała linijka, ale musisz dodać pierwszą 1 (na wszelki wypadek) –

3

Możesz pominąć instrukcję if, korzystając z poniższej konstrukcji, ale to niekoniecznie oznacza, że ​​jest lepsza.

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

Spróbuj 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 
+2

Wymaga to co najmniej 1 rekordu o wartości pustej dla Nazwa –

+0

Moja zła. Myślałem, że on ma wartość null .. –

+0

Możesz spróbować tego również –

2

Przypuszczam, że można używać @@ ROWCOUNT aby sprawdzić, czy zostaną zwrócone.

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

Możesz także użyć zmiennej, jeśli spodziewasz się jednego wiersza.

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 
2

Sugerowałbym, że najlepszym sposobem na zrobienie tego jest najpierw zadeklarowanie @name. Następnie ustaw tę wartość na podstawie identyfikatora użytkownika, a następnie, jeśli @name ma wartość null, wyświetl domyślną nazwę, inaczej wyświetl nazwę ... Ta metoda byłaby tak samo skuteczna, jak każda inna metoda, i będzie bardziej czytelna. W przypadku innych metod, każdy inny użytkownik pomyśli o dużo wiedzieć, co się dzieje, chyba że jest ładny komentarz.

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') 
0
Try this 
`SELECT IFNULL(Name,'John Doe') FROM Users WHERE Id = @UserId)` 
Powiązane problemy