1

データはかなり大きく、毎回実行するのに数分かかるため、この問題のデバッグには多くの時間がかかります。小さいデータで実行する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;

comment でありsourcedataitemあるnon_informative

からのいくつかのアイテムT.item:

「株式分析 -」、「#InsideTrades」、「IIROCトレード」

削除すべきコメントの例

'#InsideTrades #4 | MACNAB CRAIG (取締役、役員、最高経営責任者): $NNN (NATIONAL RETA'

なぜすべてのアイテムを表示するのか理解できないようです

4

3 に答える 3

1

non_informativedataテーブルの間にデカルト積があります。(列がどのテーブルからのものかはまったく明確ではありませんticker

non_informative「コメント」が返されるために必要なのは、(クエリの述語を満たすために)コメントと「一致」しない行が 1 つ見つかることだけであることを理解してください。一致する non_informative の行があるかもしれませんが、クエリはそれらを気にしません。クエリは、一致しない行の存在のみを探しています。クエリは、non_informative のすべての行に一致する場合にのみ「コメント」が除外されることを効果的に示しています。


non_informative に一致する行がない "comment" の値を返したい場合は、別のクエリが必要です。ticker(列はテーブルからのものであると仮定しdataます。)

の空の文字列値のコーナー ケースも除外しますitem。これは、comment のすべての非 null 値に本質的に「一致」するためです。


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

これら 2 つのステートメントは、同等の結果セットを返します (ただし、元のクエリの結果セットとは異なります)。また、異なるパフォーマンス特性を示す可能性があります (MySQL のバージョンや、MySQL エンジンが NOT EXISTS 述語を結合防止操作に変換できるかどうかによって異なります...パフォーマンスは、使用可能なインデックスと生成されるインデックスによって異なります)。実行計画。)

空の文字列のコーナーケースを気にしなければ、2 番目のステートメントを少し単純化できます...

 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 に答える
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 に答える
0

明確な答えはありませんが、ケースを調査するためのいくつかの可能なステップを提案することができます。

  1. あなたはエラーとは何かを示さなかったのですか?同様のエラーがたくさんありますか?

  2. 同様の操作でエラーが発生したことを確認しましたか?

  3. Devartのアイデアはありそうです。異なるエンコーディングの混合は、奇妙なバグの原因となる可能性があります。一部の値でのみ失敗する可能性があります。アイテムのフィールドタイプとは何ですか?convert(mysql help)を使用できます。

  4. おそらく、locateまたはinstr関数の呼び出しのように置き換えることができます。

于 2012-12-13T16:57:12.907 に答える