我写的这句话在所有情况下都能正常工作,除了一个案例
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行。为什么呢?
答案 0 :(得分:5)
这是由于NOT IN子句中NULL的行为造成的。
例如,
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
。
条件为空
评估为UNKNOWN的条件几乎就像FALSE。对于 例如,一个带有WHERE子句中的条件的SELECT语句 计算到UNKNOWN不返回任何行。但是,一个条件评估 UNKNOWN与UNKNOWN的进一步操作不同于FALSE 条件评估将评估为UNKNOWN。因此,不要错 计算结果为TRUE,但NOT UNKNOWN计算结果为UNKNOWN。
答案 1 :(得分:1)
您需要使用OUTER JOIN:
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');
答案 2 :(得分:0)
这是正确的命令:
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') ;