MYSQL CONCAT + GROUP_CONCAT + LEFT OUTER JOIN

时间:2018-03-26 10:54:58

标签: mysql concat group-concat

我正在尝试在mySQL上的两个表之间建立链接,但我认为它比我想象的要困难一些。

我有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');

我要做的是通过一个列来获取我的所有规则,该列将所有链接的传输收集为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

但这会给我一个“空”值。我不明白我做错了什么。 有人可以帮我吗?

仅供参考,我受到了这个链接的启发 MySQL: GROUP_CONCAT with LEFT JOIN

1 个答案:

答案 0 :(得分:1)

使用5.7.22之前的MySQL版本,您无法使用JSON内置函数。

您必须使用一些重叠的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上下文中的给定aeroport关联到单个字符串中。

这给出了以下封装:

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)