Оператор case в предложении where в SQL Server, если переменная имеет какое-либо значение, иначе сравнивает текущую - PullRequest
0 голосов
/ 10 мая 2018

У меня есть 2 таблицы Account и Roles. Я хочу получить всех пользователей, независимо от того, имеют ли они какую-либо роль или нет. Но когда я запускаю запрос ниже, он возвращает только пользователей, которые играют какую-либо роль в таблицах Roles, но не возвращает пользователей, которые не имеют никакой роли.

Я проверяю, есть ли какое-либо значение в переменной @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)

Ответы [ 4 ]

0 голосов
/ 10 мая 2018

Вам просто нужно СЛЕДУЮЩЕЕ НАРУЖНОЕ СОЕДИНЕНИЕ здесь:

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
0 голосов
/ 10 мая 2018

Вы можете поместить условие в объединение (ON), чтобы получить все результаты из таблицы Account, даже если результаты не совпадают с ролями.

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)
0 голосов
/ 10 мая 2018

попробуйте так:

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))
0 голосов
/ 10 мая 2018

Осторожно, когда вы ставите условия на 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)
.
...