2

首先,请注意我对 SQL(在本例中为 sqlite3)几乎没有经验,因此即使这个问题的标题也可能措辞不当。

假设我有一个笔记表 ( n),以及这些笔记的关键字表 ( k),最后是一个将一个或多个关键字与每个笔记相关联的表 ( nk)。我想做的是找到每个包含两个(或更多)关键字的注释。

更具体地说,下面(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 的注释。我在网络上进行了一些搜索,但恐怕我的知识不足以想到好的搜索词。我希望这个网站上的人可以提供帮助,而且——重要的是——如果这是一个愚蠢的问题,我深表歉意。

4

3 回答 3

1

如果您只想要包含两个以上关键字的笔记,请使用聚合:

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子句只是在看到其中一个值时创建一个标志。然后,该逻辑确定在给定音符的关键字集中是否已经看到该值。

于 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)

kid即使kid可能存在其他值(3,4 等), 这也会得到匹配 1 和 2 的记录。sqlfiddle 在这里

于 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 回答