我有两个sql表: wall 表和 tag 表。他们每个人都与具有“ _和_belongs_to_many”关系相关联。标签表也具有唯一的名称。
这是sql中的表
mysql> describe tags;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | UNI | NULL | |
| count | int(11) | NO | | NULL | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL | |
+------------+--------------+------+-----+---------+----------------+
mysql> describe tags_walls;
+---------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------+------+-----+---------+-------+
| tag_id | bigint(20) | NO | MUL | NULL | |
| wall_id | bigint(20) | NO | | NULL | |
+---------+------------+------+-----+---------+-------+
mysql> describe walls;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL | |
+------------+--------------+------+-----+---------+----------------+
我正在使用Rails 5,我想查询具有多个标签的墙。
我正在尝试
result = Wall.all.includes(:tags).where(tags: {name: 'TAG1'})
result = result.where(tags: {name: 'TAG2'})
,由rails构造的查询是
SELECT DISTINCT `walls`.`id`
FROM `walls`
LEFT OUTER JOIN `tags_walls` ON `tags_walls`.`wall_id` = `walls`.`id`
LEFT OUTER JOIN `tags` ON `tags`.`id` = `tags_walls`.`tag_id`
WHERE `tags`.`name` = 'TAG1' AND `tags`.`name` = 'TAG2'
它应该给我多堵墙,但返回值为#<ActiveRecord::Relation []>
我想构建一个自定义的sql查询,然后执行
Wall.includes(:tags).where query
如何对由AND链接的多个条件的联接表进行WHERE查询?
答案 0 :(得分:1)
我会这样写:
SELECT tw.id
FROM tags_walls tw JOIN
tags t
ON t.id = tw.tag_id
WHERE t.name IN ('TAG1', 'TAG2')
GROUP BY tw.id
HAVING COUNT(*) = 2;
这假定标签在墙上没有重复。如果可能的话,请使用COUNT(DISTINCT t.name) = 2
。
注意:
walls
不需要,因此JOIN
被删除。INNER JOIN
比LEFT JOIN
更合适。答案 1 :(得分:0)
WHERE tags.name = 'TAG1' OR tags.name = 'TAG2'
或
WHERE tags.name IN ('TAG1','TAG2')
答案 2 :(得分:0)
SELECT w.id
FROM walls w
JOIN tags_walls tw
ON tw.wall_id = w.id
JOIN tags t
ON t.id = tw.tag_id
AND t.name IN('TAG1','TAG2')
GROUP
BY w.id
HAVING COUNT(DISTINCT t.name) = 2 -- where '2' equals the number of arguments in IN()