0

2 つのテーブルがあり、テーブル 2 のエントリの 1 つを含むテーブル 1 のすべてのエントリ (行ごとに複数の単語) を削除しようとしています。テーブル 2 のこれらの単語は、テーブル 1 の文字列のどこかにある可能性があります。

'house' in 'big house here' または in 'big house' のようなものを見つける必要があります。

次のようなものは検出されません。「houses」内の「house」

次のようにロケート機能を使用しようとしました。

CREATE TABLE `test`
AS (
  SELECT
    `table1`.`term1`,
    `table2`.`term2`
  FROM `table1`,`table2`
  WHERE
    locate(concat(' ',`table2`.`term2`,' '), concat(' ',`table1`.`term1`,' '))
);

問題は、すべてではなく一部を見つけることであり、すべてに対して機能しない理由の背後にあるロジックがわかりません。

4

1 に答える 1

0

探している単語が句読点で囲まれている場合、一致は機能しません。

フィールド内のすべての句読点をスペースに置き換えることができます。

ただし、よりクリーンなソリューションは正規表現になると思います:

CREATE TABLE test
AS
SELECT table1.term1, table2.term2
FROM table1, table2
WHERE table1.term1 REGEXP CONCAT('(^|[^A-Za-z]])',table2.term2,'([^A-Za-z]|$)');

(^|[^A-Za-z])フィールドの開始を意味するか、AZ または az ではありません。
([^A-Za-z]|$)AZ または az またはフィールドの終わりではないことを意味します。

SQLフィドル

編集:

上記はきれいですが、特に効率的ではありません。(140 ms小さなテストで)

より効率的: ( 80 ms、適切なデータでははるかに優れている可能性があります)

SELECT term1, term2
FROM table1, table2
WHERE term1 LIKE CONCAT('%',term2,'%')
  AND term1 REGEXP CONCAT('(^|[^A-Za-z])',term2,'([^A-Za-z]|$)');

より効率的な方法: ( 8 ms) (奇妙な理由により、MySQL は正規表現をうまく処理できないようです)

SELECT COUNT(*)
FROM table1, table2
WHERE term1 LIKE CONCAT(term2,' %')
   OR term1 LIKE CONCAT(term2,',%')
   OR term1 LIKE CONCAT(term2,'.%')
   OR term1 LIKE CONCAT(term2,';%')
   OR term1 LIKE CONCAT('% ',term2,' %')
   OR term1 LIKE CONCAT('% ',term2,',%')
   OR term1 LIKE CONCAT('% ',term2,'.%')
   OR term1 LIKE CONCAT('% ',term2,';%')
   OR term1 LIKE CONCAT('% ',term2)

少し効率的: ( 4 ms)

SELECT COUNT(*)
FROM table1, table2
WHERE CONCAT(' ', REPLACE(REPLACE(REPLACE(term1, ',', ' '), '.', ' '), ';', ' '), ' ')
        LIKE CONCAT('% ',term2,' %')

上記の文字をさらにいくつか含めることができます。

SQLフィドル

上記の多くはデータに依存することに注意してください。一部のケースではより効率的であり、他のケースでは非常に悪い場合があります(ただし、正規表現はおそらく遅れをとります)。

さらに効率的?

フルテキスト インデックス + 検索

于 2013-03-04T11:08:08.717 に答える