拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 从另一个表中选择不包含单词的行

从另一个表中选择不包含单词的行

白鹭 - 2022-03-04 1972 0 0

我有一个每行一个单词的表格和一个连续有一些文本的表格。我只需要从第二个表中选择那些不包含第一个表中单词的行。

例如:

带有约束词的表

约束字
例子
苹果
橘子
蘑菇
qwerty

带文字的表格

文本
词 1。苹果word3,例子
word1,苹果,word2。
word1 word2橙色word3
蘑菇word1 word2 word3
word1
qwerty

在这种情况下不应选择任何内容,因为第二个表中的每一行都包含第一个表中的单词。

我只有一个想法CROSS JOIN来实作这一目标

SELECT DISTINCT text FROM text_table CROSS JOIN words_table
           WHERE CONTAINS(text, constraint_word ) = 0

有没有办法在不使用的情况下做到这一点CROSS JOIN

uj5u.com热心网友回复:

contains指 Oracle 文本;交叉连接意味着笛卡尔积(通常是性能噩梦)。

避免这两种情况的一个选项是instr函式(检查 in 的存在constraint_wordtext但这次使用内部连接)和minus集合运算子。

像这样,使用您发布的示例资料:

SQL> select * from text_table;

TEXT
---------------------------
word1.apple; word3, example
word1, apple, word2.car
word1 word2 orange word3
mushroomword1 word2 word3
word1 car
qwerty

6 rows selected.

SQL> select * From words_table;

CONSTRAI
--------
example
apple
orange
mushroom
car
qwerty

6 rows selected.

SQL>

正如您所说,最初查询不应回传任何内容,因为所有内容都constraint_words存在于text

SQL> select c.text
  2  from text_table c
  3  minus
  4  select b.text
  5  from words_table a join text_table b on instr(b.text, a.constraint_word) > 0;

no rows selected

让我们修改其中text一行:

SQL> update text_table set text = 'xxx' where text = 'qwerty';

1 row updated.

现在结果如何?

SQL> select c.text
  2  from text_table c
  3  minus
  4  select b.text
  5  from words_table a join text_table b on instr(b.text, a.constraint_word) > 0;

TEXT
---------------------------
xxx

SQL>

对; 我们刚刚修改的文本。

uj5u.com热心网友回复:

您的想法很好,因为您需要测验每个文本的所有单词。这就是 CROSS JOIN 所做的 - 组合(笛卡尔积)。

我们甚至可以更严格地获得更好的性能并使用 INNER JOIN 或简写JOIN

另请参阅:SQL 中的 CROSS JOIN 与 INNER JOIN

此外,您需要过滤所有text没有匹配项的记录。这意味着每个组合中不匹配的计数text是最大值(= 约束字数,此处为 6)。这个过滤器可以使用GROUP BYWITHHAVING

-- text without any constaint_word
SELECT t.text, count(*)
FROM text_table t
JOIN words_table w ON CONTAINS(t.text, w.constraint_word, 1) = 0
GROUP BY t.text
HAVING count(*) = (SELECT count(*) FROM words_table)
;

它将输出:

文本 数数(*)
蘑菇word1 word2 word3 6

在SQL Fiddle上尝试演示

整个单词与部分匹配

请注意,约束词中的“蘑菇”不匹配,CONTAINS因为它包含为词部分而不是整个词。

对于部分匹配,您可以使用LittlefootINSTR的回答

也可以看看

  • 在 oracle SQL 查询中使用字符串包含函式
  • PL-SQL 中的 contains() 是如何作业的?
  • Oracle 背景关系索引
  • 创建和维护 Oracle 文本索引

uj5u.com热心网友回复:

我相信这行得通(我认为CROSS JOIN路线的问题在于它包含任何不包含至少一个单词的文本——不仅仅是不包含任何单词的文本):

SELECT DISTINCT text FROM text_table WHERE (SELECT COUNT(*) FROM words_table WHERE CONTAINS(text, constraint_word)) = 0;
标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *