1

私のデータベースは次のように構築されています:

  1. value1、value2、value3 | 1
  2. value4、value5、val "u6 | 2
  3. 値5、値6、値8 | 3

(2つの列。1つはコンマで区切られたキーを持ち、もう1つは通常のvar-charだけです)

引用符内でクエリを見つけるための最も信頼できる方法を探していますが、ここで少し迷っています。

私はそのために境界という言葉を使用しています:

SELECT * FROM ABC WHERE content REGEXP '[[:<:]]value 5[[:>:]]'

問題は、私がこのクエリを実行しているときです。

SELECT * FROM ABC WHERE content REGEXP '[[:<:]]5[[:>:]]'

また、私が探しているものではない値を返します。もう1つの問題は、単語の境界が引用符を単語の境界と呼んでいることです。

これを解決して、引用符の間の正確な完全なクエリのみをフェッチする単純なクエリを作成するにはどうすればよいですか?

ところで、DB構造を変更するオプションはありません...

4

2 に答える 2

4

@MarcBがコメントしたように、スキーマを正規化することを実際に試みる必要があります。

CREATE TABLE ABC_values (
  id  INT,
  content VARCHAR(10),
  FOREIGN KEY (id) REFERENCES ABC (id)
);

INSERT INTO ABC_values
  (id, content)
VALUES
  (1, 'value1'), (1, 'value2'), (1, 'value3'),
  (2, 'value4'), (2, 'value5'), (2, 'val"u6'),
  (3, 'value 5'), (3, 'value 6'), (3, 'value 8')
;

ALTER TABLE ABC DROP content;

次に、必要に応じて、テーブル間でSQL結合を実行し、結果をグループ化できます。

SELECT   id, GROUP_CONCAT(ABC_values.content) AS content
FROM     ABC LEFT JOIN ABC_values USING (id) NATURAL JOIN (
  SELECT id FROM ABC_values WHERE content = 'value 5'
) t
GROUP BY id

スキーマを変更することが完全に不可能な場合は、次のことを試すことができますFIND_IN_SET()

SELECT * FROM ABC WHERE FIND_IN_SET('value 5', content)
于 2012-12-03T15:04:56.893 に答える
0

別の回避策は、リスト内のアイテムの区切り文字でLIKEを使用することです。

WHERE content LIKE ',5,'

ただし、探しているアイテムはリストの最初または最後にある可能性があります。したがって、リストをその場で変更して、開始と終了に区切り文字を含める必要があります。

WHERE CONCAT(',', content, ',') LIKE '%,5,%'  -> this works for me on mysql

これは機能し、ある意味では、コンマ区切りのリスト内のアイテムを検索する他の検索よりも悪くはありません。これは、このような検索はテーブルスキャンを実行する必要があるため、非常に非効率的であるためです。テーブル内のデータが大きくなるにつれて、有用であるほど十分に機能しないことがわかります。

データベース列に区切りリストを格納することは本当に悪いですか?に対する私の答えも参照してください。

于 2012-12-03T15:17:16.590 に答える