В чем проблема в этом SQL-заявлении? - PullRequest
0 голосов
/ 24 июля 2011

Я пишу это утверждение, которое работает правильно во всех случаях, кроме одного случая

SELECT p.priv_no FROM osqs_privileges p,osqs_users_privileges up 
WHERE up.priv_no = p.priv_no AND up.user_no = 54 AND up."GRANT" = 'Y' 
    UNION 
SELECT p.priv_no FROM 
osqs_privileges p,osqs_groups_privileges gp,osqs_users_groups ug,osqs_users_privileges up 
    WHERE gp.priv_no = p.priv_no AND ug.grp_no = gp.grp_no AND ug.user_no = 54 
AND gp.priv_no NOT IN 
    (SELECT priv_no FROM osqs_users_privileges WHERE user_no = 54 AND "GRANT" = 'N');

в случае, если у osqs_users_privileges нет строк, и этот оператор (SELECT priv_no FROM osqs_users_privileges WHERE user_no = 54 AND "GRANT" = 'N') возвращает 0 строк, все сценарии возвращают 0 строк, даже если операторы выбора othe возвращают данные. почему?

Ответы [ 3 ]

5 голосов
/ 24 июля 2011

Это связано с поведением NULL в предложении NOT IN.

Например,

select 'yes' where 3 in (1, 2, 3, null)  -- Return result
select 'yes' where 3 not in (1, 2, null) -- Returns an empty set

Почему?Потому что 3 <> null приводит к UNKNOWN.

Null в условиях

Условие, которое оценивается как UNKNOWN, действует почти как FALSE.Например, инструкция SELECT с условием в предложении WHERE, которое оценивается как UNKNOWN, не возвращает строк.Однако условие оценки UNKNOWN отличается от FALSE тем, что дальнейшие операции оценки состояния UNKNOWN будут оцениваться как UNKNOWN.Таким образом, NOT FALSE оценивается как TRUE, но NOT UNKNOWN оценивается как UNKNOWN.

Ref .

1 голос
/ 24 июля 2011

Вам нужно использовать НАРУЖНОЕ СОЕДИНЕНИЕ:

SELECT p.priv_no FROM osqs_privileges p,osqs_users_privileges up 
WHERE up.priv_no = p.priv_no AND up.user_no = 54 AND up."GRANT" = 'Y' 
    UNION 
SELECT p.priv_no 
FROM osqs_privileges p
LEFT JOIN osqs_groups_privileges gp on osqs_users_groups ug on gp.priv_no = p.priv_no
LEFT JOIN osqs_users_privileges up on ug.grp_no = gp.grp_no
WHERE ug.user_no = 54 
AND gp.priv_no NOT IN 
    (SELECT priv_no FROM osqs_users_privileges WHERE user_no = 54 AND "GRANT" = 'N');
0 голосов
/ 24 июля 2011

это правильная команда:

    SELECT p.priv_no FROM osqs_privileges p,osqs_users_privileges up 
WHERE up.priv_no = p.priv_no AND up.user_no = 55 AND up."GRANT" = 'Y' 
    UNION 
SELECT p.priv_no 
FROM osqs_privileges p 
LEFT JOIN osqs_groups_privileges gp on gp.priv_no = p.priv_no 
LEFT JOIN osqs_users_groups ug on ug.grp_no = gp.grp_no 
LEFT JOIN osqs_users_privileges up on up.priv_no = p.priv_no 
WHERE ug.user_no = 55 
AND gp.priv_no NOT IN 
    (SELECT priv_no FROM osqs_users_privileges WHERE user_no = 55 AND "GRANT" = 'N') ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...