【问题标题】:How to join arrays with MySQL from 3 tables of many-to-many relationship如何从 3 个多对多关系表中将数组与 MySQL 连接
【发布时间】:2018-08-23 02:42:43
【问题描述】:

我在本地服务器中使用 phpMyAdmin 创建了一个 mySQL 数据库。在这个数据库中,我存储了我朋友的名字和最喜欢的 NBA 球队。这显然是一个多对多的关系。出于这个原因,我在 MySQL 中运行以下脚本来为该数据库创建适当的表:

CREATE TABLE `friends` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL,
  PRIMARY KEY (`id`)
)

CREATE TABLE `teams` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL,
  PRIMARY KEY (`id`)
)

CREATE TABLE `relations` (
  `friends_id` int(4) NOT NULL,
  `teams_id` int(4) NOT NULL,
)

显然,我在这些表中插入了一些值,但我没有在此处提供大量源代码以节省一些空间。一小部分如下:

INSERT INTO `friends` (`id`, `name`)
VALUES
    (1,'David Belton'),
    (2,'Alex James');

INSERT INTO `teams` (`id`, `name`)
VALUES
    (1,'Cleveland Cavaliers'),
    (2,'Boston Celtics');

INSERT INTO `relations` (`friends_id`, `teams_id`)
VALUES
    (1,1),
    (2,1),
    (2,2);

在运行一个从数据库中获取数据并打印出来的 PHP 脚本后,我希望为我的每个朋友提供以下类型的有效 json 输出:

{
    "id": "1",
    "name": "Alex James",
    "team": ["Boston Celtics", "Cleveland Cavaliers"] 
}

如何为每个使用 MySQL 的人制作这些最喜欢的团队?

附: 我假设这最好在用 PHP 检索数据之前在 MySQL 中完成。

【问题讨论】:

  • 您能给您的表格提供一些示例数据吗? |因为您的 JSON 示例只给出了一行!多用户 JSON 响应应该是什么样子? “P.S. 我假设最好在使用 PHP 检索数据之前在 MySQL 中完成。”不是真的在 PHP 中生成 JSON 数据要容易得多。
  • 您使用的是哪个版本的 MySQL?
  • 抱歉耽搁了@RaymondNijland。我编辑了帖子。
  • 我想你正在寻找这样的东西:stackoverflow.com/questions/21760969/…
  • No @Sander 这被标记为 MySQL 而不是 SQL-server

标签: php mysql json


【解决方案1】:

“简单”的方法是使用 CONCAT 生成 JSON。
并使用 GROUP_CONCAT 将多个团队记录组合成一个 JSON 数组。
此方法也适用于不支持创建 JSON 函数的旧 MySQL 版本。

查询

SET SESSION group_concat_max_len = @@max_allowed_packet

SELECT 
 CONCAT(
     "{"
   ,     '"id"' , ":" , '"' , friends.id , '"' , ","
   ,     '"name"' , ":" , '"' , friends.name , '"' , ","
   ,     '"team"' , ":" , "["
                              , GROUP_CONCAT('"', teams.name, '"')
                        , "]"
   , "}"
   ) AS json
FROM 
 friends 
INNER JOIN 
 relations 
ON 
 friends.id = relations.friends_id
INNER JOIN
 teams 
ON
 relations.teams_id = teams.id
WHERE 
 friends.id = 1

结果

|                                                            json |
|-----------------------------------------------------------------|
| {"id":"1","name":"David Belton","team":["Cleveland Cavaliers"]} |

演示

http://www.sqlfiddle.com/#!9/4cd244/19

编辑了更多朋友

查询

SET SESSION group_concat_max_len = @@max_allowed_packet

SELECT
  CONCAT(
      "["
    , GROUP_CONCAT(json_records.json) # combine json records into a string
    , "]"
  )  AS json
FROM (

  SELECT 
     CONCAT(
       "{"
     ,     '"id"' , ":" , '"' , friends.id , '"' , ","
     ,     '"name"' , ":" , '"' , friends.name , '"' , ","
     ,     '"team"' , ":" , "["
                              , GROUP_CONCAT('"', teams.name, '"')
                          , "]"
     , "}"
     ) AS json 
  FROM 
    friends 
  INNER JOIN 
    relations 
  ON 
    friends.id = relations.friends_id
  INNER JOIN
    teams 
  ON
    relations.teams_id = teams.id
  WHERE 
    friends.id IN(SELECT id FROM friends) #select the friends you need or just simply friends.id IN(1, 2)
  GROUP BY
     friends.id
) 
 AS json_records

结果

|                                                                                                                                             json |
|--------------------------------------------------------------------------------------------------------------------------------------------------|
| [{"id":"1","name":"David Belton","team":["Cleveland Cavaliers"]},{"id":"2","name":"Alex James","team":["Boston Celtics","Cleveland Cavaliers"]}] |

演示

http://www.sqlfiddle.com/#!9/4cd244/61

【讨论】:

  • 非常好的一个。但是,您没有向我显示拥有两支最喜欢球队的“亚历克斯·詹姆斯”的结果,这就是我问这个问题的原因。
  • Alex isfriend.id = 2 您需要更改 WHERE 语句.. 检查 sqlfiddle 演示还有 alex 示例.. 您的示例 JSON 仅使用一条记录,因此我基于我的答案那.. 除了您的 JSON 示例之外,还混合了 David Belton 和 Alex James 的数据。
  • 抱歉,部分原因是我在帖子中的错误。
  • 非常好的答案,很抱歉延迟将其勾选为正确。
  • 但是,您想编辑您的帖子(或写一个真正分析性的评论)来解释我如何为许多friends_id 执行此操作吗?我应该使用计数器变量和 while 循环吗?
猜你喜欢
  • 1970-01-01
  • 2012-02-02
  • 2019-08-22
  • 1970-01-01
  • 2015-09-05
  • 2018-11-06
  • 1970-01-01
  • 2010-11-25
  • 1970-01-01
相关资源
最近更新 更多