我正在使用标记过滤功能为自己构建一个笔记记录应用程序,但在尝试使用标记抓取笔记时遇到问题。标签过滤器需要使用AND而不是IN,因为它有助于更好地缩小我正在寻找的内容。
我的表格配置如下:
+ notes note_id | note_title | note_uid
+ tags tag_id | tag_title
+ notes_tags nt_id | nt_note_id | nt_tag_id
notes_tags表跟踪所有音符的标签。
我并不担心会返回有关标记的任何信息,所以这里有一个示例LEFT JOIN我目前只使用仅<1> 标记来获取笔记。
SELECT * FROM notes_tags LEFT JOIN注释ON note_id = nt_note_id WHERE note_uid IN(1)AND nt_tag_id = 10
此查询运行完美,它会使用单个标记抓取所有注释。但是,我遇到的问题是使用如下查询“精确定位”我的笔记:
SELECT * FROM notes_tags LEFT JOIN注释ON note_id = nt_note_id WHERE note_uid IN(1)AND nt_tag_id = 10 AND nt_tag_id = 11
我在语法上做错了什么?
答案 0 :(得分:2)
nt_tag_id = 10 AND nt_tag_id = 11
这将始终返回false
使用nt_tag_id in (10,11)
代替
如果你需要两个标签,下面有两次加入标签表的答案
答案 1 :(得分:2)
这将仅返回两者 tag_id 10和11的注释。
SELECT notes.*
FROM notes
INNER JOIN notes_tags a ON notes.note_id = a.nt_note_id
AND a.nt_tag_id = 10
INNER JOIN notes_tags b ON notes.note_id = b.nt_note_id
AND b.nt_tag_id = 11
答案 2 :(得分:2)
假设您要识别与nt_tag_ids 10和nt_tag_ids为11的相关notes_tags记录的注释,那么外部联接只会让DBMS更加努力地工作。
这似乎是最明显的解决方案:
SELECT * FROM notes n
WHERE EXISTS (SELECT 1 FROM notes_tags nt
WHERE n.note_id=nt.nt_note_id
AND nt.nt_tag_id=10)
AND EXISTS (SELECT 1 FROM notes_tags nt2
WHERE n.note_id=nt2.nt_note_id
AND nt2.nt_tag_id=11);
另一种方法是:
SELECT n.*, COUNT(*)
FROM notes n,
notes_tags nt
WHERE n.note_id-nt.nt_note_id
AND nt.nt_tag_id IN (10,11)
GROUP BY .... /* need to add these */
HAVING COUNT(*)=2;
请注意,这预先假定它们是notes_tags表中nt_note_id和nt_tag_id的唯一约束。
但以上两者都只会返回notes表中的数据。如果需要从MN分解表中提取相应的行:
SELECT *
FROM notes n,
notes_tags nt,
notes_tags nt2
WHERE n.note_id=nt.nt_note_id
AND n.note_id=nt2.note_id
AND nt.nt_note_id=nt2.nt_note_id /* can help the optimizer come up with a faster query */
AND nt.nt_tag_id=10
AND nt2.nt_tag_id=11
您可能希望在输出列中添加别名,以便更轻松地解析响应。
答案 3 :(得分:0)
你正在使用'AND'而不是在where子句中使用'OR',如下所示:
SELECT * FROM notes_tags LEFT JOIN notes ON note_id = nt_note_id WHERE note_uid IN ( 1 ) AND (nt_tag_id = 10 OR nt_tag_id = 11)
如果要添加更多nt_tag_id,也可以使用IN。
SELECT * FROM notes_tags LEFT JOIN notes ON note_id = nt_note_id WHERE note_uid IN ( 1 ) AND nt_tag_id IN (10, 11)