1

数据相当大,每次运行都需要几分钟,所以调试这个问题需要很多时间。当我like concat('%',T.item,'%')在较小的数据上运行时,它似乎可以正确识别项目。但是,当我在主数据库(显示的代码)上运行它时,它仍然显示许多(甚至可能是全部)异常。

编辑:似乎当我添加 NOT 它停止识别项目

select distinct T.comment
from (select comment, source, item from data, non_informative where ticker != "O" and source != 7 and source != 6) as T
where T.comment not like concat('%',T.item,'%')
order by T.comment;

comment 和sourcedata,itemnon_informative

一些项目来自T.item

“股票分析 -”、“#InsideTrades”、“IIROC 贸易”

应删除的示例注释

'#InsideTrades #4 | MACNAB CRAIG(董事、高级职员、首席执行官):为 $NNN 提交表格 4(NATIONAL RETA'

似乎无法弄清楚为什么显示所有项目

4

3 回答 3

1

(旧查询已删除)

试试这个查询 -

SELECT comment FROM data, non_informative
WHERE ticker != 'O' AND source != 7 AND source != 6
  GROUP BY comment
HAVING COUNT(IF(comment LIKE CONCAT('%', item, '%'), 1, NULL)) = 0
于 2012-12-13T16:33:02.090 回答
1

你在non_informativedata表之间有一个笛卡尔积。(根本不清楚该列ticker来自哪个表。

了解要返回的“评论”,所需要的(满足查询中的谓词)就是找到non_informative与评论不“匹配”的一行。non_informative 中可能有匹配的行,但您的查询并不关心这些。您的查询只是寻找不匹配的行的存在。该查询实际上是说,只有当它与非信息性中的每一行匹配时,才会排除“评论”。


如果您要返回的是 non_informative 中没有匹配行的“comment”值,则需要不同的查询。(我将假设该ticker列来自data表格。)

我还将排除空字符串值的极端情况item,因为这将基本上“匹配”每个非空值以进行注释。


SQL小提琴在这里

-- 使用 NOT EXISTS 谓词:

 SELECT d.comment
   FROM `data` d
  WHERE d.ticker != 'O'
    AND d.source != 7
    AND d.source != 6
    AND NOT EXISTS
        ( SELECT 1
            FROM `non_informative` n
           WHERE n.item <> ''
             AND d.comment LIKE CONCAT('%',n.item,'%')
        )
  GROUP BY d.comment
  ORDER BY d.comment

-- 或者,使用反连接:

 SELECT d.comment
   FROM `data` d
   LEFT
   JOIN ( SELECT n.item
            FROM `non_informative` n
           WHERE n.item <> ''
           GROUP BY n.item
        ) m
     ON d.comment LIKE CONCAT('%',m.item,'%')
  WHERE d.ticker != 'O'
    AND d.source != 7
    AND d.source != 6
    AND m.item IS NULL
  GROUP BY d.comment
  ORDER BY d.comment

这两个语句应该返回一个等效的结果集(但与原始查询的结果集不同)。它们也可能表现出不同的性能特征(取决于 MySQL 的版本,以及 MySQL 引擎是否可以将 NOT EXISTS 谓词转换为反连接操作......性能实际上取决于可用的索引和生成的索引执行计划。)

如果我们不关心空字符串的极端情况,我们可以稍微简化第二个语句......

 SELECT d.comment
   FROM `data` d
   LEFT
   JOIN `non_informative` n
     ON d.comment LIKE CONCAT('%',n.item,'%')
  WHERE d.ticker != 'O'
    AND d.source != 7
    AND d.source != 6
    AND n.item IS NULL
  GROUP BY d.comment
  ORDER BY d.comment

基本上,对于表中的每一行data,我们都在检查表中的“匹配” non_informative。对于我们找到“匹配”的任何行,该行将被“n.item IS NULL”谓词排除。对于data在 中找不到匹配行的任何行non_informative,LEFT JOIN 操作将为“item”列生成 NULL 值,因此该行将包含在结果集中。


表现:

您的原始查询包括一个内联视图(别名为t)。MySQL 将在外部查询运行之前将其实现为中间 MyISAM 表。这种想法可能是大型表的真正性能杀手。

但在我们“调整”该语句之前,我们确实需要一个返回正确结果集的语句。(如果它没有返回所需的结果集,那么重写该语句是没有意义的,除非作为练习。)

于 2012-12-13T16:52:44.857 回答
0

我没有明确的答案,但我可以建议一些可能的步骤来调查此案。

  1. 你没有显示什么是错误?有很多类似的错误吗?

  2. 您是否检查过类似操作导致错误?

  3. 德瓦特的想法似乎是可能的。不同编码的混合可能是奇怪错误的来源。它只能对某些值失败。什么是项目的字段类型?您可以使用转换(mysql帮助)。

  4. 可能您可以用定位或 instr 函数的调用替换 like。

于 2012-12-13T16:57:12.907 回答