如何使OUTER JOIN返回ZERO而不是NULL

时间:2017-05-27 10:33:47

标签: sql sql-server select outer-join

我试图在SQL Server上完成此任务。包含数据的最简单的表结构如下所示。

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子句中提供的UserID始终是有效的UserID,并且存在于User表中。

1 个答案:

答案 0 :(得分:3)

您可以将userID = 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);