SQL 服务器中 where 子句中的 Case 语句如果变量有任何值,否则比较当前

Case statement in where clause in SQL Server if variable have any value otherwise compare current

我有 2 个表 AccountRoles。我想获得所有用户,无论他们是否有任何角色。但是当我在下面查询 运行 时,它 return 只有在 Roles 表中具有任何角色的用户,而不是 return 没有任何角色的用户。

我正在检查@role_id 变量中是否有任何值,然后将其与@role_id 进行比较,否则与当前值进行比较。正确吗?

SELECT 
    a.user_id, a.username, a.first_name, a.last_name, a.division_id,   
    a.dept_id, a.email, a.password, a.IsAdmin, a.status, a.cdate, a.mdate 
FROM 
    Account AS a 
LEFT JOIN 
    Roles r ON a.user_id = r.user_id
WHERE 
    r.role_id = (CASE 
       WHEN @role_id IS NOT NULL AND @role_id <> '' THEN @role_id ELSE r.role_id 
    END)

WHERE 上附加可选条件时要小心,它们应该作为 LEFT JOIN 上的附加条件。

SELECT 
    a.user_id, a.username, a.first_name, a.last_name, a.division_id,   
    a.dept_id, a.email, a.password, a.IsAdmin, a.status, a.cdate, a.mdate 
FROM 
    Account AS a 
LEFT JOIN 
    Roles r ON a.user_id = r.user_id
AND 
    (@role_id IS NULL OR @role_id = r.role_id)

您可以将条件放在联接 (ON) 中,以便从帐户 table 中获取所有结果,即使结果与角色一不匹配。

SELECT 
    a.user_id, a.username, a.first_name, a.last_name, a.division_id,   
    a.dept_id, a.email, a.password, a.IsAdmin, a.status, a.cdate, a.mdate 
FROM 
    Account AS a 
LEFT JOIN 
    Roles r ON a.user_id = r.user_id
               and
               r.role_id = (
               CASE 
                    WHEN ISNULL(@role_id, '') = '' THEN r.role_id
               ELSE @role_id
               END)

试试这个方法:

SELECT a.user_id, a.username, a.first_name, a.last_name, a.division_id, a.dept_id, a.email,
a.password, a.IsAdmin, a.status, a.cdate, a.mdate FROM Account AS a 
LEFT JOIN Roles r on a.user_id = r.user_id
WHERE ((ISNULL(@role_id,'') = '') OR (r.role_id = @role_id))

这里只需要一个 LEFT OUTER JOIN:

SELECT 
    a.user_id, a.username, a.first_name, a.last_name, a.division_id, 
    a.dept_id, a.email, a.password, a.IsAdmin, a.status, a.cdate, a.mdate, CASE WHEN r.user_id IS NULL THEN 'NO' ELSE 'YES' END AS HAS_ROLE 
FROM 
    Account AS a 
LEFT OUTER JOIN
    Roles r ON a.user_id = r.user_id