在多个一对多表上通过Mysql在g​​roup by上获取数据的问题

时间:2019-06-11 15:09:52

标签: mysql sql

当前我们有三个表

用户(用于存储基本信息)

  • id-> PK
  • 名字->索引
  • 姓->索引

此表中还有许多字段通常用于过滤数据


user_titles (与表A的一对多关系表。我们通常用来在表A上存储用户的标题。单个用户可以从一个表中获得多个标题可以是主要的,另一个可以是 中学

  • id
  • user_id(从FK到表A)
  • title_id(FK到标题表,我们将存储所有标题名称)
  • is_primary(枚举->'primary','secondary')

user_speciality (表是与用户表的一对多关系,我们在其中存储用户的主要专业和其他专业)

  • id-> PK
  • user_id->(FK,对用户表的引用)
  • specialty_id->(FK,指向存储专业信息的专业表的引用)
  • is_primary->(枚举->'primary','secondary')

因此,上面是表格的严格性,在搜索时,我们必须列出所有具有所选专业和职务的用户。

基于此表结构,我们按以下查询方式获取数据

> SELECT `user_titles`.`title_id`,`user_titles`.`is_primary`,`user_speciality`.`speciality_id`,`user_speciality`.`is_primary`,`users`.`firstname`,`users`.`lastname`FROM `users`, `user_titles`,`user_speciality` where `user_speciality`.`user_id`=`users`.`id` and `user_titles`.`user_id`=`users`.`id`

但是,当我们列出数据时,如果用户具有次要标题或专业,则会为用户获得多行。基本上我需要数据采用以下格式。

当我们在上面的查询中使用group_concat时,我们收到一条错误消息,指出无法进行group_concatgroup by

user_id, title_id(primary), title_ids(secondary titles with comma seperated), user.firstname, user.lastname, speciality_id(primary), specialty_id(secondary id's with comma separated)

如果我们将标题和专业ID以逗号分隔的值存储在用户表中并编写一个类似的查询,则可以很容易地获得此结构,但是我们拥有大量的数据,并且在这些查询中,类似查询的性能令人怀疑数据。

请指导我们解决问题。

1 个答案:

答案 0 :(得分:2)

从不FROM子句中使用逗号。 始终使用正确的,明确的,标准 JOIN语法。

也就是说,您想要的是聚合。特别是,您可以使用条件聚合来完成您想做的事情:

SELECT u.*,
       MAX(CASE WHEN ut.is_primary THEN ut.title_id END) as primary_title,
       GROUP_CONCAT(DISTINCT CASE WHEN NOT ut.is_primary THEN ut.title_id END) as secondary_titles,
       MAX(CASE WHEN us.is_primary THEN us.speciality_id END) as primary_specialty,
       GROUP_CONCAT(DISTINCT CASE WHEN NOT us.is_primary THEN us.speciality_id END) as secondary_specialties
FROM `users` u LEFT JOIN
     `user_titles` ut
     ON ut.user_id = u.id LEFT JOIN
     `user_speciality` us
     ON us.`user_id`= u.`id` 
GROUP BY u.id;