简体   繁体   English

Mysql连接来自三个表的数据(很多关系)

[英]Mysql join data from three tables (many to many relations)

this is my mysql db schema: 这是我的mysql数据库模式:

数据库模式 I would like to create query that would return data about all trainings in a following way : 我想创建查询,该查询将通过以下方式返回有关所有培训的数据:

training.*, [type.type], [voivodeship.name] if there would be no type or voivodeship related to given training it should return null in the column value. training。*,[type.type],[voivodeship.name]如果没有与给定培训相关的类型或省份,则应在列值中返回null。

For example: 例如:

 {
    "id": 1,
    "name": "Example training 2",
    "description": "This is a description 2",
    "status": "status 2",
    "registerFrom": null,
    "registerTo": null,
    "DateOfInsert": "2018-02-06T12:00:57.000Z",
    "training types": "Example type 1,Example type 3,Example type 2"
    "localizations": "loc 1, loc 3"
 },
...
 {
    "id": 99,
    "name": "Example training 99",
    "description": "This is a description 99",
    "status": "status 2",
    "registerFrom": null,
    "registerTo": null,
    "DateOfInsert": "2018-02-06T12:00:57.000Z",
    "training types": null,
    "localizations": null
 },
 {
    "id": 99,
    "name": "Example training 99",
    "description": "This is a description 99",
    "status": "status 2",
    "registerFrom": null,
    "registerTo": null,
    "DateOfInsert": "2018-02-06T12:00:57.000Z",
    "training types": "Example type 9,Example type 4,Example type 2",
    "localizations": "loc 56, loc 32"
  },

this is my current query that returns trainings with information about its localizations (sadly it doesnt return the ones without them) and i also dont have idea how to modify it to return also all types: 这是我当前的查询,它返回有关本地化信息的培训(可悲的是,没有本地化信息,它不会返回本地化信息),而且我也不知道如何修改它以返回所有类型的信息:

SELECT `training`.*, GROUP_CONCAT(`voivodeship`.`name`) AS `Localizations`
FROM `training_localization` 
INNER JOIN `training` ON (`training_localization`.`training_id` = `training`.`id`) 
INNER JOIN `voivodeship` ON (`training_localization`.`voivodeship_id` = `voivodeship`.`id`) 
GROUP BY `training`.`id`

I am not very experienced with sql. 我对sql不太有经验。 Is it even possible with one query? 一个查询甚至可能吗?

According to Gordon answer i made new query, at it seems like it's working :): 根据戈登的答案,我提出了新的查询,看来它正在工作:):

SELECT t.*, GROUP_CONCAT(vs.name) AS Localizations,  tw.types AS types
FROM training t 
     LEFT JOIN training_localization tl ON tl.training_id = t.id 
     LEFT JOIN voivodeship vs ON tl.voivodeship_id = vs.id
     LEFT JOIN(
        SELECT t.*, GROUP_CONCAT(ty.type) AS Types
        FROM training t 
             LEFT JOIN training_type tt ON tt.training_id = t.id 
             LEFT JOIN type ty ON tt.type_id = ty.id
        GROUP BY t.id
        ) tw ON tw.id = t.id
GROUP BY t.id;

If you want all of something, think "outer join". 如果您想要所有东西,请考虑“外部加入”。 If you want all trainings, that should be the first table in a series of left join s: 如果要进行所有培训,则应该是一系列left join s中的第一个表:

SELECT t.*, GROUP_CONCAT(vs.name) AS Localizations
FROM training t LEFT JOIN
     training_localization tl
     ON tl.training_id = t.id LEFT JOIN 
     voivodeship vs
     ON tl.voivodeship_id = vs.id
GROUP BY t.id;

Notes: 笔记:

  • LEFT JOIN s keep everything in the first table and matching rows in the subsequent tables (unless you undo it with an inner join or where clause). LEFT JOIN将所有内容保留在第一个表中,并将匹配的行保留在后续表中(除非您使用内部join或where子句将其撤消)。
  • Table aliases make the query easier to write and to read. 表别名使查询更易于编写和阅读。
  • Eliminating unnecessary backticks makes the query easier to write and to read. 消除不必要的反引号使查询更易于编写和阅读。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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