【问题标题】:Passing a delimited string in the NOT IN clause在 NOT IN 子句中传递分隔字符串
【发布时间】:2017-12-19 23:34:16
【问题描述】:

下面的 SQL 从概念上复制了我试图解决的问题。尽管传递了 NOT IN 子句,但所有三个记录都会返回。

SELECT * FROM (
SELECT 'JACK' AS VALUE FROM DUAL
UNION
SELECT 'JOHN' AS VALUE FROM DUAL
UNION
SELECT 'BOB' AS VALUE FROM DUAL
) WHERE VALUE NOT IN (SELECT 'BOB,JOHN' FROM DUAL);

我有一个表,其中包含一个分隔字符串,我想将其用作从数据集中排除记录的条件。但是,我遇到的问题是返回的字符串没有分解为其分隔项。我希望将以上内容翻译为:

SELECT * FROM (
SELECT 'JACK' AS VALUE FROM DUAL
UNION
SELECT 'JOHN' AS VALUE FROM DUAL
UNION
SELECT 'BOB' AS VALUE FROM DUAL
) WHERE VALUE NOT IN ('BOB','JOHN');

【问题讨论】:

  • 您有一个包含分隔字符串的表?为什么?如果您正确使用数据库并单独存储字符串,则编写查询不会有问题。
  • 返回所有三个记录,因为'BOB,JOHN' 是一个单个字符串值。显然是'BOB,JOHN' != 'BOB''BOB,JOHN' != 'JACK''BOB,JOHN' != 'JOHN'。所以结果是正确的。问题是您将集合存储为字符串而不是更合适的内容,例如数组或表格。
  • 您好,感谢您的 cmets 并完全同意。我会使用表格来保存值,但在我工作的公司中采用了这种方法,因此我必须按照我原来帖子中描述的方式工作。

标签: oracle plsql


【解决方案1】:

您可以使用 regexp_substr 解决该问题:

SELECT * FROM (
SELECT 'JACK' AS VALUE FROM DUAL
UNION
SELECT 'JOHN' AS VALUE FROM DUAL
UNION
SELECT 'BOB' AS VALUE FROM DUAL
)
WHERE VALUE NOT IN (SELECT regexp_substr('BOB,JOHN','[^,]+', 1, LEVEL) FROM dual CONNECT BY regexp_substr('BOB,JOHN', '[^,]+', 1, LEVEL) IS NOT NULL)

【讨论】:

  • 发布一段代码并说“使用这个”不是最好的帮助,如果没有解释 OP 代码的问题是什么以及解释为什么(以及如何)你的代码解决了问题.
  • 那从哪里开始和结束呢?他知道 substr 是什么吗?他是否知道正则表达式是什么以及如何使用它们。他知道connect by是什么吗?如果他有任何进一步的问题,他可以问他们,我愿意提供帮助。但我很难猜测他还需要什么信息。
【解决方案2】:

'BOB,JOHN' 不是两个字符串值的列表,它是一个字符串值,恰好在字符串中包含一个逗号,并且:

'JACK' = 'BOB,JOHN'
'JOHN' = 'BOB,JOHN'
'BOB'  = 'BOB,JOHN'

全部为假,因此您的查询将返回与 NOT IN 过滤器匹配的所有行。

您可以用分隔符包围您的值和列表,并测试该值是否不是列表的子字符串,如下所示:

SELECT *
FROM (
  SELECT 'JACK' AS VALUE FROM DUAL UNION ALL
  SELECT 'JOHN' AS VALUE FROM DUAL UNION ALL
  SELECT 'BOB'  AS VALUE FROM DUAL
)
WHERE INSTR( ',' || 'BOB,JOHN' || ',', ',' || value || ',' ) = 0

或者您可以使用用户定义的集合:

CREATE OR REPLACE TYPE stringlist IS TABLE OF VARCHAR2(20);

然后使用MEMBER OF运算符来测试一个值是否是集合的成员:

SELECT *
FROM (
  SELECT 'JACK' AS VALUE FROM DUAL UNION ALL
  SELECT 'JOHN' AS VALUE FROM DUAL UNION ALL
  SELECT 'BOB'  AS VALUE FROM DUAL
)
WHERE  VALUE NOT MEMBER OF StringList( 'BOB', 'JOHN' );

【讨论】:

    猜你喜欢
    • 2013-06-04
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    • 2013-07-03
    • 2022-11-15
    相关资源
    最近更新 更多