繁体   English   中英

MySql多对多搜索

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM