0

私の質問を説明するために作成した以下のデータベーステーブルを参照してください。

CREATE Table Test(id int not null IDENTITY,data varchar(100))
INSERT INTO Test(data) values ('Simon')
INSERT INTO Test(data) values ('David;James;Michael') 

以下のSQLステートメントを参照してください。

select *
from Test
where data like '%_James%'
    or data like '%James;%'

セミコロンが常に区切り文字として使用されていると仮定すると、テーブルセルに1つの名前があるか複数の名前があるかに関係なく、Jamesは常に検出されると思います。

別の開発者は、値を配列(ASP.NETまたはその他のプログラミング言語)にロードし、配列をループして完全に一致するものを見つけると述べましたが、「James」は常に見つかった。このステップは必要ですか?

4

3 に答える 3

2

クエリでフィルタリングすることをお勧めします。何百万ものレコードがあったとしたら? フィルタリングするためだけに、最初にすべてを取得する必要はありません。

この非正規化されたスキーマに固執する必要があると仮定すると、私は次のようにします。最初の 2 つのケースでは、列のインデックスを利用できdataます。データの先頭または末尾にセミコロンがないことを前提としています。

select * 
from Test 
where data = 'James'
    or data like 'James;%'
    or data like '%;James;%' 
    or data like '%;James' 
于 2012-04-16T18:35:05.900 に答える
1

いいえ、配列に値をロードする必要はありません。いずれにせよ、パフォーマンスが非常に悪くなります。

あなたのSQLは少し奇妙だと言いました-名前を挿入したい場合は、次のもの;が必要だと思います:

INSERT INTO Test(data) values ('David;James;Michael') 

おそらく、すべての名前がセパレーターで開始および終了することを確認すると、さらに良いでしょう:

INSERT INTO Test(data) values (';David;James;Michael;') 

次に、使用できます

SELECT * FROM Test WHERE data like '%;James;%'

常に正しい結果が得られるようにしてください。

最後になりましたが、1 つの列に複数の評価者を詰め込むことはできますが、SQL データベースで行うのは最善の方法ではありません。別のテーブルの別々の行に名前を保持してからクロスを作成することをお勧めします。 -それへの参照 (構造の正規化)。

于 2012-04-16T18:36:50.117 に答える
1

貼り付けた SQL を使用すると、james の前に少なくとも 1 文字ある場合 (例: "2James"、"BJames"、"2Jamesey" が一致)、または "james" の後にセミコロンがある場合 (例: "2James;"、"BJames;"、"James")。ただし、アンダースコアを使用しているため、「James」自体は一致しません。

あなたがやろうとしていることは正確には明らかではありません。"James" という単語 ("James" の前後に "単語" の境界がある) と完全に一致する行のみを検索しますか?より大きな単語の一部、たとえば「Jamestown」)。を追加することで修正できますor data = 'James'。あなたの全体的な目標が何であるかわからないので、アンダースコアがあなたが望むことをしているかどうかはわかりません。クエリをさらに変更する必要がある場合とない場合があります。

テーブル内のデータがクリーンであるという確信に応じて、自分の言うことを実行するステートメントを作成できます。場合によっては非効率になる可能性があるため、レコードを取り出して配列内の値をループするのではなく、SQL ステートメント内で検索を保持します。

于 2012-04-16T18:33:43.483 に答える