2017-05-27 78 views
0

これをSQL Serverで実行しようとしています。データを持つ最も単純なテーブル構造を以下に示します。OUTER JOINをNULLの代わりに0を返す方法

Table:Blog 

BlogID, Title 
---------------- 
1, FirstBlog 
23, Pizza 

Table:User 

UserID, Name 
------------------- 
123, james 
444, John 


Table:UserBlogMapping 

UserBlogMappingID, BlogID,UserID 
---------------------------------- 
1, 1, 123 

1つのSQLクエリでFormIDとUserBlogMappingIDを取得したいとします。提供されたUserIDがマッピングテーブルにない場合は、ゼロを返し、それ以外の場合は有効なuserBlogMappingIDを返します。私は以下のクエリを実行しようとしていますが、それは正しくありません。

SELECT 
    B.BlogID, 
    BUM.BlogUserMappingID 
FROM 
    Blog AS B 
     LEFT JOIN BlogUserMapping AS BUM ON B.BlogID = BUM.BlogID 
WHERE 
    (B.BlogID = 23) -- it exists in the table 
    AND BUM.userID = 444 -- it is NOT in the mmaping table but i want a ZERO return in such case 

仮定: 我々はWHERE句で提供ユーザーIDは、常に有効なユーザーIDで、Userテーブルに存在すると仮定することができます。

答えて

3

LEFT JOINのON句にuserID = 444の条件を設定できます。

とテーブル変数を使用して0にNULLを変更するには、ISNULLまたはCOALESCE

例:

declare @Blog table (BlogID int, Title varchar(30)); 
insert into @Blog (BlogId, Title) values 
(1, 'FirstBlog'), 
(23, 'Pizza'); 

declare @User table (UserID int, Name varchar(30)); 
insert into @User (UserID, Name) values 
(123,'james'), 
(444,'John'); 


declare @BlogUserMapping table (BlogUserMappingID int, BlogID int, UserID int); 
insert into @BlogUserMapping (BlogUserMappingID, BlogID, UserID) values 
(1, 1, 123), 
(2, 23, 123), 
(3, 1, 444); 


-- Using the criteria in ON clause of the LEFT JOIN 
SELECT 
B.BlogID, 
ISNULL(BUM.BlogUserMappingID,0) as BlogUserMappingID 
FROM @Blog B 
LEFT JOIN @BlogUserMapping BUM ON (B.BlogID = BUM.BlogID AND BUM.userID = 444) 
WHERE B.BlogID = 23; 

-- If there are more BlogId=23 with userID=444. 
-- But only 1 row needs to be returned then you could also GROUP BY and take the maximum BlogUserMappingID 
SELECT 
B.BlogID, 
MAX(ISNULL(BUM.BlogUserMappingID,0)) as BlogUserMappingID 
FROM @Blog B 
LEFT JOIN @BlogUserMapping BUM ON (B.BlogID = BUM.BlogID AND BUM.userID = 444) 
WHERE B.BlogID = 23 
GROUP BY B.BlogID; 

-- Using an OR in the WHERE clause would also return a 0. 
-- But it would also return nothing if the mapping table has a BlogID=23 with a userID<>444. 
-- So not usefull in this case. 
SELECT 
B.BlogID, 
ISNULL(BUM.BlogUserMappingID,0) as BlogUserMappingID 
FROM @Blog B 
LEFT JOIN @BlogUserMapping BUM ON B.BlogID = BUM.BlogID 
WHERE B.BlogID = 23 
    AND (BUM.userID IS NULL OR BUM.userID = 444); 
+0

あなたは私たちが「BUM.userID = 444」続けると確信していますLEFT JOIN句には含まれていませんか? – user1451111

+1

@LukStormsいいえ、同じことをしません。同じ結果を達成する別の方法ではありません。 'LEFT JOIN'がマッチしたときに何が起こるか考えてみましょう。ただし、' BUM.userID <> 444'の行にのみマッチします。 – hvd

+0

@hvdさて、私はそれを変更しました。投稿する前にマッピングテーブルの23でテストしてください。アドバイスをいただきありがとうございます。 – LukStorms

関連する問題