MYSQL CONCAT + GROUP_CONCAT + 左外连接

MYSQL CONCAT + GROUP_CONCAT + LEFT OUTER JOIN

我正在尝试在 mySQL 的 2 个表之间创建一个 link,但是,我认为这比我想象的要难一些。

我有3张桌子 * 注册我的规则信息的一个 * 一个注册我的转账信息的 * 一个首先使两者之间的支点。

CREATE TABLE `rules` (
  `id` int,
  `Name` varchar(10)
);

INSERT INTO `rules` (`id`, `name`) VALUES
(1,'a'),
(2,'b'),
(3,'c'),
(4,'d');

CREATE TABLE `pivot` (
  `id_rule` int,
  `id_transfert` int
);

INSERT INTO `pivot` (`id_rule`, `id_transfert`) VALUES
(1,1),
(1,2),
(2,1),
(2,2),
(2,3);

CREATE TABLE `transferts` (
  `id` int,
  `aeroport` varchar(50),
  `station` varchar(50)
);

INSERT INTO `transferts` (`id`, `aeroport`,`station`) VALUES
(1,'GVA','Flaine'),
(2,'GNB','La Tania'),
(3,'GNB','Flaine');

我想要做的是通过一个列获取我的所有规则,该列将所有 linked 传输收集为 JSON 字符串。喜欢下面

------------------------------------------------------------------------
|  id   |  name  |  transferts                                         |
------------------------------------------------------------------------
|  1    |   a    | {"GVA": "Flaine"}                                   |
------------------------------------------------------------------------
|  2    |   b    | {"GVA": "Flaine", "GNB": "Flaine", "La Tania"}      |
------------------------------------------------------------------------

我实际上是这样做的:

SELECT
      rule.id, rule.name,GROUP_CONCAT(stations.transferts SEPARATOR ",") as transferts
                FROM
                    rules rule
                LEFT OUTER  JOIN  
                    pivot pivot 
                on
                    (pivot.id_rule = rule.id)
                LEFT OUTER  JOIN  
                    (
                        SELECT id, 
                        CONCAT(aeroport, ":",
                        GROUP_CONCAT(station)
                        ) AS transferts
                        FROM transferts
                        GROUP BY aeroport
                    ) stations         
                on
                    (pivot.id_transfert = stations.id)
                GROUP BY
                    rule.id

但这会返回一个 "null" 值。我不明白我做错了什么。 请问有人可以帮助我吗?

仅供参考,我受到了启发link MySQL: GROUP_CONCAT with LEFT JOIN

对于 5.7.22 之前的 MySQL 版本,您无法使用 JSON built-in 功能。

您将不得不使用一些嵌套的 GROUP_CONCAT 子查询来获取您的 JSON 字符串。

如评论中所述,您预期的 JSON 字符串无效。以下答案将与您的预期结果不同,以解决此问题。

我建议您继续进行第一个查询,以获取具有 "aeroport" 名称的列,以及另一列具有格式化为列表的关联站的列,用于每对 "rule.id + aeroport_name".

这给出了以下查询:

mysql> select rules.id, name, concat ('"', aeroport, '":') as aeroport_name, group_concat('"', station, '"') as station_list
    -> from rules
    -> inner join pivot on rules.id = pivot.id_rule
    -> inner join transferts on pivot.id_transfert = transferts.id
    -> group by rules.id, aeroport_name;
+------+------+---------------+---------------------+
| id   | name | aeroport_name | station_list        |
+------+------+---------------+---------------------+
|    1 | a    | "GNB":        | "La Tania"          |
|    1 | a    | "GVA":        | "Flaine"            |
|    2 | b    | "GNB":        | "La Tania","Flaine" |
|    2 | b    | "GVA":        | "Flaine"            |
+------+------+---------------+---------------------+
4 rows in set (0,00 sec)

然后,我们将使用此查询作为子查询,将每个 "station_list" 与其给定的机场相关联,在规则 ID 上下文中,在单个字符串中。

这样封装如下:

mysql> select id, name, group_concat(aeroport_name, '[', station_list, ']') as aeroport_list
    -> from (
    ->    select rules.id, name, concat ('"', aeroport, '":') as aeroport_name, group_concat('"', station, '"') as station_list
    ->    from rules
    ->    inner join pivot on rules.id = pivot.id_rule
    ->    inner join transferts on pivot.id_transfert = transferts.id
    ->    group by rules.id, aeroport_name
    -> ) as isolated group by id;
+------+------+----------------------------------------------+
| id   | name | aeroport_list                                |
+------+------+----------------------------------------------+
|    1 | a    | "GNB":["La Tania"],"GVA":["Flaine"]          |
|    2 | b    | "GNB":["La Tania","Flaine"],"GVA":["Flaine"] |
+------+------+----------------------------------------------+
2 rows in set (0,00 sec)

最后,我们现在可以将最终的“{}”封装添加到我们的字符串中,为此添加一个顶级查询:

mysql> select id, name, concat('{', aeroport_list, '}') as conf                                                                                                                                                                                   
    -> from (
    ->    select id, name, group_concat(aeroport_name, '[', station_list, ']') as aeroport_list
    ->    from (
    ->       select rules.id, name, concat ('"', aeroport, '":') as aeroport_name, group_concat('"', station, '"') as station_list
    ->       from rules
    ->       inner join pivot on rules.id = pivot.id_rule
    ->       inner join transferts on pivot.id_transfert = transferts.id
    ->       group by rules.id, aeroport_name
    ->    ) as isolated group by id
    -> ) as full_list;
+------+------+------------------------------------------------+
| id   | name | conf                                           |
+------+------+------------------------------------------------+
|    1 | a    | {"GNB":["La Tania"],"GVA":["Flaine"]}          |
|    2 | b    | {"GNB":["Flaine","La Tania"],"GVA":["Flaine"]} |
+------+------+------------------------------------------------+
2 rows in set (0,01 sec)