OR子句返回错误结果SQL Developer

时间:2018-05-14 15:52:28

标签: sql oracle oracle-sqldeveloper

我在包含用户名和用户ID的表上编写查询。我想忽略包含以下任何字符串的用户名:

LOCKED, 停用, CLOSED

记录用户ID为1234且用户名为#34; myusername已锁定"作为一个例子

以下查询仍会返回此记录

select username 
from table where (
instr(username),'LOCKED') = 0
or instr(username),'CLOSED') = 0
or instr(username),'DEACTIVATED') = 0
) and userid = '1234'

我希望不会返回任何结果,因为虽然用户ID 1234确实存在,但如果没有字符串" LOCKED"在用户名中。

为什么要返回记录?

是因为其他条件是真的吗?即。有一个ID为1234的记录,用户名不包含"已关闭"? (因为它包含"已锁定"

2 个答案:

答案 0 :(得分:4)

如果任何条件为or,则true运算符会返回true。也就是说,即使其中一个为false,但其他两个为true,结果为true

或:

false true true -> true
false false true -> true

如果任何条件为and,则false运算符会返回false

false true true -> false
false false true -> false

我认为您想要的是AND运算符。 在你脑海中想想“如果Y是真的,如果X是真的那么___”。您以前拥有的是“如果Y为真或者如果X为真___”,当然这将返回true

所以解决方案是:

select username 
from table
where (instr(username), 'LOCKED') = 0 and
      instr(username), 'CLOSED') = 0 and
      instr(username), 'DEACTIVATED') = 0
     ) and
    userid = '1234'

答案 1 :(得分:0)

Gordon_Linoff有正确的答案,但我喜欢使用常见的表格表达式(CTE),所以我想我会添加这个额外的答案,以防您想要将排除名称作为CSV提供而不是将其硬编码到SQL。

   WITH
    user_table
    AS
        -- set up some usernames for testing
        (SELECT 'ARBY' AS username
           FROM DUAL
         UNION ALL
         SELECT 'CLOSED'
           FROM DUAL
         UNION ALL
         SELECT 'GOOFY'
           FROM DUAL),
    csv_value
    AS
        (SELECT 'LOCKED, CLOSED, DEACTIVATED' csv
           FROM DUAL),
    exclude_uservalues
    AS
        --  1) Bracket CSV value with commas
        --  2) Remove any spaces (presumes no embedded spaces within CSV values)
        (SELECT ',' || REPLACE (csv, ' ', NULL) || ',' AS csv_values
           FROM csv_value),
    exclude_userset (
                        exclude_user, csv_values
                    )
    AS
        -- This common table expression will split the CSV values into separate records
        -- It works by
        --   a) extracting the value between the first two commas
        --   b) dropping everything before the second comma
        --   c) terminating when there is no second comma
        (SELECT SUBSTR (csv_values, 2, INSTR (csv_values, ',', 2) - 2) AS exclude_user
              , SUBSTR (csv_values, INSTR (csv_values, ',', 2)) AS csv_values
           FROM exclude_uservalues
         UNION ALL
         SELECT SUBSTR (csv_values, 2, INSTR (csv_values, ',', 2) - 2) AS exclude_user
              , SUBSTR (csv_values, INSTR (csv_values, ',', 2)) AS csv_values
           FROM exclude_userset
          WHERE INSTR (csv_values, ',', 2) > 0)
SELECT username
  FROM user_table LEFT OUTER JOIN exclude_userset ON username = exclude_user
 WHERE exclude_user IS NULL;

这个废话的结果是:

USERNAME
--------
GOOFY
ARBY