不喜欢不与列进行比较

时间:2012-12-13 16:16:16

标签: mysql

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

编辑: 它似乎当我添加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;

commen t和source位于dataitem位于non_informative

T.item的一些项目:

  

'股票分析 - ','#IntrasTrades','IIROC Trade'

应删除的评论示例

  

'#InsideTrades#4 | MACNAB CRAIG(董事,总监,行政总裁   官员):提交表格4 $ NNN(NATIONAL RETA'

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

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

了解要返回的“注释”,所有必需的(以满足查询中的谓词)是在non_informative中找到一行而不匹配注释的行。 non_informative中可能存在匹配的行,但您的查询并不关心这些行。您的查询仅查找不匹配的行的存在。该查询实际上是说,如果“评论”与非信息中的每一行匹配,则将仅排除“评论”。


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

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


SQL Fiddle here

- 使用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表实现。而这种想法可能是一个真正的表演杀手与大桌子。

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

答案 2 :(得分:0)

我没有明确的答案,但我可以提出一些可能的步骤来调查案件。

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

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

  3. Devart的想法似乎很可能。混合不同的编码可能是奇怪的错误的来源。它只能因某些值而失败。什么是字段类型的项目?您可以使用convert(mysql help)。

  4. 您可以像调用locate或instr函数一样替换。