查询M:N包含

时间:2018-03-07 00:58:39

标签: sql sqlite android-room junction-table

我正在尝试过滤一组包含Android Room(SQLite)中M:N联结表的表。

图像可以包含许多主题。我想允许主题过滤,以便获得包含完整图像信息(包括所有主题)的行。因此,如果图像(国家公园,优胜美地)过滤任何一个都会导致一行包含两个关键字。除非我搞砸了,否则典型的连接会产生多行,这样匹配Yosemite就能得到正确的图像,但是你缺少National Park。我想出了这个:

SELECT *,  
  (SELECT GROUP_CONCAT(name) 
    FROM meta_subject_junction
    JOIN subject 
      ON subject.id = meta_subject_junction.subjectId
      WHERE meta_subject_junction.metaId = meta.id) AS keywords, 
  (SELECT documentUri
    FROM image_parent
    WHERE meta.parentId = image_parent.id ) AS parentUri
FROM meta

现在这给了我完整的行,但我想在这一点上我需要:

WHERE keywords LIKE(%YOSEMITE%)

我认为LIKE不太理想,更不用说不精确的匹配了。有没有更好的方法来实现这一目标?谢谢,这是我的新手SQL大脑的弯曲。

更多细节

meta
+----+----------+--+
| id |   name   |  |
+----+----------+--+
|  1 | yosemite |  |
|  2 | bryce    |  |
|  3 | flowers  |  |
+----+----------+--+
subject
+----+---------------+--+
| id |     name      |  |
+----+---------------+--+
|  1 | National Park |  |
|  2 | Yosemite      |  |
|  3 | Tulip         |  |
+----+---------------+--+
junction
+--------+-----------+
| metaId | subjectId |
+--------+-----------+
|      1 |         1 |
|      1 |         2 |
|      2 |         1 |
|      3 |         3 |
+--------+-----------+

虽然我可能做错了什么,据我所知,Android会议室并不喜欢:

+----+-----------+---------------+
| id |   name    |    subject    |
+----+-----------+---------------+
|  1 | yosemite  | National Park |
|  1 | yosemite  | Yosemite      |
+----+-----------+---------------+

所以我试图减少行数:

+----+-----------+-------------------------+
| id |   name    |         subject         |
+----+-----------+-------------------------+
|  1 | yosemite  | National Park, Yosemite |
+----+-----------+-------------------------+

以上查询的内容。但是,我也想查询一个主题。因此National Park过滤器将产生:

+----+-----------+-------------------------+
| id |   name    |         subject         |
+----+-----------+-------------------------+
|  1 | yosemite  | National Park, Yosemite |
|  2 | bryce     | National Park           |
+----+-----------+-------------------------+

我希望比已经' concat'更加精确/高效。学科。我的大部分尝试最终都没有在Room(多行)中显示结果,或者只将主题缩小为filter关键字。

更新

这是我用来将查询的实际SQL结果与Android Room最终结果进行比较的测试:

http://sqlfiddle.com/#!7/0ac11/10/0

该连接查询被解释为Android Room中的四个对象,因此我尝试减少行数,但在过滤包含主题关键字的任何图像时保留完整的主题结果。

2 个答案:

答案 0 :(得分:0)

如果您想要多个关键字,则可以使用header = False match_count = 0 for apt in aptList: if userInput >= htl.room and userInput <= htl.fee: header=True ## shouldnt this statement get it to print? if header==True: print('{:10} {:10}'.format('Room#','Fee')) print(htl.getApt()) match_count += 1 if match_count == 0: header=False where以及group by

having

答案 1 :(得分:0)

这会得到我需要的结果,但如果效率特别低,我会喜欢听到更好的选择。

SELECT meta.*, 
  (SELECT GROUP_CONCAT(name)
    FROM junction
    JOIN subject 
      ON subject.id = junction.subjectId
      WHERE junction.metaId = meta.id) AS keywords,
  junction.subjectId
FROM meta
LEFT JOIN junction ON junction.metaId = meta.id
WHERE subjectId IN (1,2)
GROUP BY meta.id

+----+----------+------------------------+-----------+
| id |   name   |        keywords        | subjectId |
+----+----------+------------------------+-----------+
|  1 | yosemite | National Park,Yosemite |         2 |
|  2 | bryce    | National Park          |         1 |
+----+----------+------------------------+-----------+

http://sqlfiddle.com/#!7/86a76/13