SQLでブールタグ検索を実装するにはどうすればよいですか?
質問
アイテムのテーブル、タグのテーブル、およびそれらの間の結合テーブルを考えると、次の形式のクエリを実装するための優れた効率的な方法は何ですか:
p1 AND p2 AND ... AND pn AND NOT n1 AND NOT n2 ... AND NOT nk
SQLを使用しています。したがって、すべてのタグp1 ... pnに一致し、n1 ... nkのどれにも一致しないすべてのアイテムを見つけるには?
良い「標準」はありますかこれに対する解決策は?
解決
スキーマを知らずに言うのは難しいですが、次のように機能します:
select article_id from articles
inner join tag t1 on t1.article_id=articles.article_id and t1.tag='included_tag'
inner join tag t2 on t2.article_id=articles.article_id and t2.tag='another_included_tag'
left outer join tag t3 on t3.article_id=articles.article_id and t3.tag='dont_include_tag'
left outer join tag t4 on t4.article_id=articles.article_id and t4.tag='also_dont_include_tag'
where t3.tag_id is null and t4.tag_id is null
含まれるタグへの内部結合、および含まれないタグへの反結合(外部結合+必要な列がnullの場合)の実行
他のヒント
これがあなたが探しているものだと思います:
SELECT * FROM TABLE_NAME WHERE COLUMN1 IN ('value1','value2','value3') AND COLUMN1 NOT IN ('value4','value5','value6')
そうでない場合はお知らせください。あなたの質問を誤解したかもしれません。
タグをデータベースに保存する方法によって異なりますが、おそらく IN
演算子が必要です:
SELECT tag FROM myTags WHERE tag IN ('p1','p2',...)
SELECT tag FROM myTags WHERE tag NOT IN ('p1','p2',...)
SELECT DISTINCT itemID FROM ItemsTags it, Tags t
WHERE it.tagID = t.ID AND t.tag IN ('p1','p2','p3') AND t.tag NOT IN ('p4','p5','p6')
SELECT i.title
FROM items i
WHERE EXISTS(SELECT * FROM join_table j JOIN tags t ON t.id = j.tag_id WHERE j.item_id = i.id AND t.name = 'tag1')
AND NOT EXISTS(SELECT * FROM join_table j JOIN tags t ON t.id = j.tag_id WHERE j.item_id = i.id AND t.name = 'tag2')
SQLサーバーはこの構成については良い仕事をしますが、Oracleはそれを正しくするためにいくつかのヒントを必要とする場合があります(少なくとも5年前はそうでした)。
所属していません StackOverflow