【问题标题】:Not select if phrase matching from records of another table不选择是否从另一个表的记录中匹配短语
【发布时间】:2022-09-22 22:16:33
【问题描述】:

我有一个大表(100M 记录),其中包含以下关键字:

(\'water\'),
(\'mineral water\'),
(\'water bottle\'),
(\'big bottle of water\'),
(\'coke\'),
(\'pepsi\')

我想选择所有记录,不包括与另一个表的至少一条记录存在正则表达式匹配的关键字。

例如,排除表包含:

  • 玻璃

所以我必须从关键字表中选择所有记录,但排除所有具有词组匹配的记录:

  • 关键字等于 \'water\' 或 \'wine\' 或 \'glass\'
  • 以 \'water\' 或 \'wine\' 或 \'glass\' 开头的关键字
  • 以 \'water\' 或 \'wine\' 或 \'glass\' 结尾的关键字
  • 关键字在两个空格的中间包含 \'water\' 或 \'wine\' 或 \'glass\'“水化”不要被排除在外。

这里是一个伪sql。期望的输出只有记录:\"coke\"、\"pepsi\"。

CREATE TABLE keywords (
  query TEXT
);
CREATE TABLE negatives (
  text TEXT
);

INSERT INTO keywords
  (query)
VALUES
  (\'water\'),
  (\'mineral water\'),
  (\'water bottle\'),
  (\'big bottle of water\'),
  (\'coke\'),
  (\'pepsi\');
  
INSERT INTO negatives (text) VALUES (\'water\', \'glass\', \'wine\');
  
SELECT *
FROM keywords 
WHERE NOT (
   query ~~ (\'% \' || \'water\' || \' %\') OR 
   query ~~ ( \'water\' || \' %\') OR 
   query ~~ (\'% \' || \'water\') OR 
   query ~~ (\'water\')
 )

https://www.db-fiddle.com/f/4ufuFAXKf7mi5yefNQqoXM/33

这需要提高性能,因为关键字表非常大(100M 记录)而“排除”表非常小(<100 条记录)

    标签: postgresql


    【解决方案1】:

    由于底片是一个合理的有界列表(您说<100 条记录),那么利用 Postgres 对数组的最出色支持怎么样?

    文字演示:

    SELECT *
    FROM keywords
    where
      not (string_to_array(query, ' ') && '{water,glass,wine}')
    

    使用您的底片表:

    with omit as (
      select array_agg (text) as neg from negatives
    )
    SELECT k.*
    FROM keywords k
    cross join omit o
    where
      not (string_to_array(k.query, ' ') && o.neg)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-06
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-27
      相关资源
      最近更新 更多