Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.3k views
in Technique[技术] by (71.8m points)

php - How to join arrays with MySQL from 3 tables of many-to-many relationship

I created a mySQL database with phpMyAdmin in my local server. In this database I store the names and the favourite NBA teams of my friends.This is obviously a many-to-many relationship. For this reason, I run the followed script in MySQL to create the appropriate tables for this database:

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,
)

Obviously, I inserted some values to these tables but I do not provide extensively the source code here so as to save some space. An small piece of it is the following:

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);

After running a PHP script that fetches the data from the database and print them, I want to have the following kind of valid json output for each of my friends:

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

How can I make this array of favourite teams for each person with MySQL?

P.S. I presuppose that this is better to be done in MySQL before the data are retrieved with PHP.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The "eazy" method is to use CONCAT to generate JSON.
And use GROUP_CONCAT to combine the multiple teams records into a JSON array.
This methode also works in the older MySQL versions that don't support create JSON functions.

Query

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

Result

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

demo

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

Edited more friends

Query

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

Result

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

demo

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...