[英]MySql many to many search
我遇到了很多问题,无法进行多次查找。 我有以下表格:
mysql> desc tags;
+------------+------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| created_at | timestamp | NO | | 0000-00-00 00:00:00 | |
| updated_at | timestamp | NO | | 0000-00-00 00:00:00 | |
| user_id | bigint(20) | NO | | NULL | |
| name | varchar(64) | NO | | NULL | |
+------------+------------------+------+-----+---------------------+----------------+
mysql> desc response_and_tag_relationships;
+-------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+-------+
| response_id | int(10) unsigned | NO | PRI | NULL | |
| tag_id | int(10) unsigned | NO | PRI | NULL | |
+-------------+------------------+------+-----+---------+-------+
mysql> desc survey_responses;
+--------------+------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| created_at | timestamp | NO | | 0000-00-00 00:00:00 | |
| updated_at | timestamp | NO | | 0000-00-00 00:00:00 | |
| survey_id | bigint(20) | NO | | NULL | |
| response | text | NO | | NULL | |
| score | smallint(6) | NO | | NULL | |
| recipient_id | bigint(20) | NO | | NULL | |
+--------------+------------------+------+-----+---------------------+----------------+
mysql> desc surveys;
+--------------+------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| created_at | timestamp | NO | | 0000-00-00 00:00:00 | |
| updated_at | timestamp | NO | | 0000-00-00 00:00:00 | |
| survey_token | varchar(255) | NO | | NULL | |
| type | smallint(6) | NO | | NULL | |
| name | varchar(255) | NO | | NULL | |
+--------------+------------------+------+-----+---------------------+----------------+
mysql> desc people;
+------------+------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| created_at | timestamp | NO | | 0000-00-00 00:00:00 | |
| updated_at | timestamp | NO | | 0000-00-00 00:00:00 | |
| email | varchar(255) | NO | | NULL | |
| last_sent | datetime | NO | | NULL | |
| name | varchar(255) | NO | | NULL | |
| dob | date | NO | | NULL | |
+------------+------------------+------+-----+---------------------+----------------+
我需要对响应中的标签进行分组。 因此,我想出了以下SQL(据我所知有限),似乎可以完成此工作:
SELECT
rat.tag_id,
rat.response_id,
t.name,
sr.response,
p.name,
p.email
FROM
response_and_tag_relationships rat
INNER JOIN tags t ON t.id=rat.tag_id
INNER JOIN survey_responses sr ON sr.id=rat.response_id
INNER JOIN surveys s ON s.id = sr.survey_id
INNER JOIN people p ON p.id=sr.recipient_id
WHERE
t.name IN (SELECT name FROM tags);
并产生以下结果:
+--------+-------------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------+-----------------------------------+
| tag_id | response_id | name | response | name | email |
+--------+-------------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------+-----------------------------------+
| 1 | 1 | ex | Repudiandae nam excepturi quasi perferendis nisi sint. Et excepturi id facere modi et sed. Eius nihil repellat veritatis voluptas. | Miss Sally Breitenberg | kkiehn@breitenberg.net |
| 3 | 1 | repudiandae | Repudiandae nam excepturi quasi perferendis nisi sint. Et excepturi id facere modi et sed. Eius nihil repellat veritatis voluptas. | Miss Sally Breitenberg | kkiehn@breitenberg.net |
| 4 | 1 | nam | Repudiandae nam excepturi quasi perferendis nisi sint. Et excepturi id facere modi et sed. Eius nihil repellat veritatis voluptas. | Miss Sally Breitenberg | kkiehn@breitenberg.net |
| 5 | 1 | excepturi | Repudiandae nam excepturi quasi perferendis nisi sint. Et excepturi id facere modi et sed. Eius nihil repellat veritatis voluptas. | Miss Sally Breitenberg | kkiehn@breitenberg.net |
| 6 | 1 | quasi | Repudiandae nam excepturi quasi perferendis nisi sint. Et excepturi id facere modi et sed. Eius nihil repellat veritatis voluptas. | Miss Sally Breitenberg | kkiehn@breitenberg.net |
| 7 | 1 | perferendis | Repudiandae nam excepturi quasi perferendis nisi sint. Et excepturi id facere modi et sed. Eius nihil repellat veritatis voluptas. | Miss Sally Breitenberg | kkiehn@breitenberg.net |
| 8 | 1 | nisi | Repudiandae nam excepturi quasi perferendis nisi sint. Et excepturi id facere modi et sed. Eius nihil repellat veritatis voluptas. | Miss Sally Breitenberg | kkiehn@breitenberg.net |
| 9 | 1 | sint | Repudiandae nam excepturi quasi perferendis nisi sint. Et excepturi id facere modi et sed. Eius nihil repellat veritatis voluptas. | Miss Sally Breitenberg | kkiehn@breitenberg.net |
但是我认为我的逻辑倒退了,因为这是响应驱动的,而不是标签驱动的(我认为...)。 我基本上只需要一个与结果匹配的标签列表即可在响应调用api方法中返回-那么有没有更好的方法呢?
编辑
我的理想结果是(尽管我不相信这是可能的):
+--------+-------------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------+-----------------------------------+
| tag_id | response_id | name | response | name | email |
+--------+-------------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------+-----------------------------------+
| 1,3,4,5,6,7,8,9 | 1 | ex | Repudiandae nam excepturi quasi perferendis nisi sint. Et excepturi id facere modi et sed. Eius nihil repellat veritatis voluptas. | Miss Sally Breitenberg | kkiehn@breitenberg.net |
我还需要在Laravel雄辩的Orm中构造它,但是我猜测最好是一个原始查询
从预期结果group_concat
可以group_concat
,它更像是您尝试对标签ID进行分组,是的,您可以使用group_concat
函数作为
SELECT
group_concat(rat.tag_id) as tag_ids,
rat.response_id,
t.name,
sr.response,
p.name,
p.email
FROM
response_and_tag_relationships rat
INNER JOIN tags t ON t.id=rat.tag_id
INNER JOIN survey_responses sr ON sr.id=rat.response_id
INNER JOIN surveys s ON s.id = sr.survey_id
INNER JOIN people p ON p.id=sr.recipient_id
group by rat.response_id
现在,上面针对每个不同的response_id
查询会将tag_id
为逗号分隔的字符串。
还要注意,当使用group by
并从多对多中选择数据时,可能会返回任何随机值,例如,如果我们在选择中保留t.name
,那么在进行t.name
之后,它可能是多对多关系中的任何一个值。
理想情况下,绝对不要在这种情况下选择这些列,也不要在诸如group_concat
类的聚合函数中使用它们。 理想的查询是
SELECT
group_concat(rat.tag_id) as tag_ids,
rat.response_id
FROM
response_and_tag_relationships rat
INNER JOIN tags t ON t.id=rat.tag_id
INNER JOIN survey_responses sr ON sr.id=rat.response_id
INNER JOIN surveys s ON s.id = sr.survey_id
INNER JOIN people p ON p.id=sr.recipient_id
group by rat.response_id
如果您还需要选择中的其他列,则如前所述,它可能是联接数据中的任何随机值。 如果要全部使用, group_concat()
对每一个使用group_concat()
。
请查看手册以了解group_concat
因为对于大型数据集,您可能需要增加group_concat_max_len
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.