4

と言う2つの列がMainありSubます。(それらは同じテーブルであってもなくてもかまいません)。

Mainは長さ 20 のSubvarchar であり、長さ 8 の varchar です。
Sub常にのサブセットでMainあり、 の最後の 8 文字ですMain

を使用して、パターンに一致するクエリを正常に設計できましたsubstr("Main",13,8)

クエリ:

select * from "MainTable"
 where substr("MainColumn",13,8) LIKE (
   select "SubColumn" From "SubTable" Where "SubId"=1043);

しかし、クエリで Like、 % 、 _ などを使用して、パターンを大まかに一致させたい (つまり、8 文字すべてではない)。

質問はどうすればそれを行うことができますか.?!

以下のクエリが完全に間違っていることはわかっていますがこのようなことを達成したいのですが、

Select * from "MainTable"
 Where "MainColumn" Like '%' Select "SubColumn" From "SubTable" Where "SubId"=2'
4

3 に答える 3

7

これまでの回答はあなたの質問に対応していません:

しかし、クエリで Like 、 % 、 _ などを使用して、パターンを大まかに一致させたい (つまり、8 文字すべてではない)。

文字列全体に一致する限り、または文字列にワイルドカード文字が含まれていない限り、LIKE使用するかどうかにほとんど違いはありません。検索をあいまいにするには、パターンに追加するだけでなく、パターンの一部を置き換える必要があります。=

たとえば、 の最後の 7 文字 (8 文字ではなく) を照合するには、次のようにしsubcolumnます。

SELECT *
FROM   maintable m
WHERE  left(maincolumn, 8) LIKE 
       ( '%' || left((SELECT subcolumn FROM subtable WHERE subid = 2), 7));

私はより単純なものを使用しますleft()(Postgres 9.1 で導入されました)。これを次のように単純化します
could

SELECT *
FROM   maintable m
WHERE  left(maincolumn, 7) =
       (SELECT left(subcolumn,7) FROM subtable WHERE subid = 2);

しかし、後で説明する特別なインデックスを使用する場合はそうはなりません。関数型インデックスの式は、使用するために正確に一致する必要があるためです。

拡張機能に興味があるかもしれませんpg_tgrm

PostgreSQL 9.1 では、データベースごとに 1 回実行します。

CREATE EXTENSION pg_tgrm;

2 つの理由:

  • 類似性演算子%を提供します。それを使用すると、スマートな類似性検索を構築できます。

    --SELECT show_limit();
    SELECT set_limit(0.5); -- adjust similarity limit for % operator
    
    SELECT *
    FROM maintable m
    WHERE left(maincolumn, 8) %
          (SELECT subcolumn FROM subtable WHERE subid = 2);
    
  • との両方のインデックス サポートを提供します。LIKE%

    書き込みパフォーマンスよりも読み取りパフォーマンスの方が重要な場合は、次のような機能的なGIN または GiST インデックスを作成することをお勧めします。

    CREATE INDEX maintable_maincol_tgrm_idx ON maintable
    USING gist (left(maincolumn, 8) gist_trgm_ops);
    

    このインデックスは、どちらのクエリもサポートしています。書き込み操作にはいくらかのコストがかかることに注意してください。
    この関連する回答 の同様のケースの簡単なベンチマーク

于 2012-07-01T13:28:11.950 に答える
2

試す

SELECT t1.* from "Main Table" AS t1, "SubTable" AS t2
 WHERE t2.SubId=1043
   AND substr(t1.MainColumn, 13, 8) LIKE "%" || CAST(t2.SubColumn as text);
于 2012-07-01T10:32:29.883 に答える
2

a の引数LIKEは通常の文字列なので、ここではすべての文字列操作が有効です。あなたの場合、@bksiが示唆するように、ワイルド文字をターゲット部分文字列と連結する必要があります。

... LIKE '%'||CAST("SubColumn" AS test) ...

ただし、そのようなパターン (%ワイルドカードで始まるパターン) はパフォーマンスが悪いことに注意してください。PostgreSQL LIKE クエリのパフォーマンスの変化を見てください。

私がお勧めします:

  • substr("MainColumn", 13, 8)現在のアプローチに固執する。
  • 代わりにLIKE等価比較 ( ) を使用しないでください (ただし、パターンにワイルドカードが含まれていない場合は等価ですが、クエリが読みやすくなります)。=LIKE
  • 次の方法で「MainTable」に式インデックスを作成します。

    CREATE INDEX i_maincolumn ON "MainTable" (substr("MainColumn", 13, 8));
    

この組み合わせは、私の見解ではより優れたパフォーマンスを発揮します。

また、テーブル/列には小文字の名前を使用して、それらを二重引用符で囲まないようにします。

于 2012-07-01T11:02:07.457 に答える