2017-05-27 43 views
0

我想在SQL Server上完成此操作。下面显示了最简单的数据表结构。如何使一个外部连接返回零而不是NULL

Table:Blog 

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

Table:User 

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


Table:UserBlogMapping 

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

我想在一个SQL查询中获取FormID和UserBlogMappingID。如果提供的UserID不在映射表中,则返回ZERO,否则返回有效的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子句中提供的用户名始终是有效的用户名和出现在用户表。

回答

3

您可以将用户ID = 444的条件放在LEFT JOIN的ON子句中。

而一个ISNULL或COALESCE使用表变量NULL更改为0。

例子:

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

相关问题