2

まず、私は SQL (この場合は sqlite3) の経験がほとんどないため、この質問のタイトルでさえ不適切な表現である可能性があることに注意してください。

ノートのテーブル ( n)、それらのノートのキーワードのテーブル ( k)、そして最後に、1 つまたは複数のキーワードを各ノートに関連付けるテーブル( ) があるとしnkます。私がやりたいことは、それぞれが 2 つ (またはそれ以上) のキーワードを含むメモを見つけることです。

もう少し具体的に言うと、以下の (sqlite3) は、データベースのセットアップ方法です。

CREATE TABLE n(nid integer primary key autoincrement, content);
CREATE TABLE k(kid integer primary key autoincrement, content);
CREATE TABLE nk(nkid integer primary key autoincrement, nid, kid);
INSERT INTO n(content) VALUES ("note 1");
INSERT INTO n(content) VALUES ("note 2");
INSERT INTO k(content) VALUES ("keyword 1");
INSERT INTO k(content) VALUES ("keyword 2");
INSERT INTO nk(nid, kid) VALUES (1, 1);
INSERT INTO nk(nid, kid) VALUES (1, 2);
INSERT INTO nk(nid, kid) VALUES (2, 1);

これで、キーワード ID 1 でタグ付けされたノートを取得できます。

select * from n LEFT JOIN nk ON nk.nid = n.nid WHERE nk.kid=1;

私の質問は、キーワード ID 12 を使用してメモを取得する方法です。Web で検索を行いましたが、私の知識では適切な検索用語を考えることができないのではないかと心配しています。このサイトの誰かが助けてくれることを願っています。重要なのは、これがばかげた質問である場合は申し訳ありません.

4

3 に答える 3

1

2 つ以上のキーワードを含むメモだけが必要な場合は、集計を使用します。

select nid
from nk
group by nid
having count(*) >= 2

キーワードがリストで重複する可能性がある場合は、次を使用します。

having count(distinct nk.kid) >= 2

キーワード 1 と 2 でメモを取得するには、次を使用します。

having max(case when kid = 1 then 1 else 0 end) = 1 and
       max(case when kid = 2 then 1 else 0 end) = 1

この場合のhaving句は、値の 1 つが表示されるたびにフラグを作成するだけです。次に、ロジックは、特定のメモの一連のキーワードでその値が見られたかどうかを判断します。

于 2013-02-12T16:03:36.433 に答える
1

@GordonLinoffの答えを改善するには:

select * from n where nid IN 
 (select nid
  from (select * from nk where kid in (1,2)) s
  group by nid
  having count(distinct s.kid) = 2)

これにより、他の値 (3、4 など) が存在する kid場合でも、1 と 2が一致するレコードが取得されます。ここで sqlfiddlekid

于 2013-02-12T16:05:30.727 に答える
0

select * from n LEFT JOIN nk ON nk.nid = n.nid WHERE nk.kid in (1,2)

于 2013-02-12T16:05:40.337 に答える