Reputation: 849
I have created a contactlist for parents in a daycare center. Now I wish to display it on the webpage. So far, it technically works perfect but it's the layout that I'm not happy with.
Short on how my database works: Each parent can have one or more children and each child can have one or more parents - a many to many relationship. I have broken it down to three tables - parents, children and parent_children in order to make a one to many relationship. Then I have used JOIN and everything displays nicely. However, since it show every entity it gets rather cluttered to display it on an webpage. I'll explain with an example:
Family 1: Mark and Alice Wilson have two children, John and Bill.
Family 2: Peter and Jessica Robertson have one child, Lisa.
Current layout:
Parent Child
-------------------------------
Mark Wilson John Wilson
Mark Wilson Bill Wilson
Alice Wilson John Wilson
Alice Wilson Bill Wilson
Peter Robertson Lisa Robertson
Jessica Robertson Lisa Robertson
-------------------------------
Desired layout:
Parent Child
-------------------------------
Mark Wilson John Wilson
Alice Wilson Bill Wilson
Peter Robertson Lisa Robertson
Jessica Robertson
-------------------------------
Is there any good way to get the desired layout?
Ok, so now I've come so far as to get this working in ONE column, depending on how I use GROUP_CONCAT:
Code:
SELECT GROUP_CONCAT(parents.name) AS Parents, children.name
FROM parents p
LEFT JOIN parents_children pc USING(id_parent)
LEFT JOIN children c USING(id_child)
GROUP BY pc.id_parent;
Result:
Parents Children
-----------------------------------------------
Mark Wilson, Alice Wilson Bill Wilson
Mark Wilson, Alice Wilson John Wilson
Peter Robertson, Jessica Robertson Lisa Robertson
Likewise, if I GROUP_CONCAT children.name and GROUP BY pc.id_child instead I get:
Parents Children
------------------------------------------
Mark Wilson Bill Wilson, John Wilson
Alice Wilson Bill Wilson, John Wilson
Peter Robertson Lisa Robertson
Jessica Robertson Lisa Robertson
I really want a combo of these, with the following result:
Parents Children
----------------------------------------------------
Mark Wilson, Alice Wilson Bill Wilson, John Wilson
Peter Robertson, Jessica Robertson Lisa Robertson
Upvotes: 1
Views: 383
Reputation: 2378
Table parents:
CREATE TABLE `parents` (
id_part
int(11) NOT NULL AUTO_INCREMENT,
parent
varchar(60) DEFAULT NULL,
PRIMARY KEY (id_part
)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8
Table child:
CREATE TABLE `child` (
id_child
int(11) NOT NULL AUTO_INCREMENT,
child
varchar(60) DEFAULT NULL,
f_name
int(11) DEFAULT NULL,
m_name
int(11) DEFAULT NULL,
PRIMARY KEY (id_child
),
KEY m_key
(m_name
),
KEY f_key
(f_name
),
CONSTRAINT f_key
FOREIGN KEY (f_name
) REFERENCES parents
(id_part
) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT m_key
FOREIGN KEY (m_name
) REFERENCES parents
(id_part
) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8
Query to join two tables
SELECT DISTINCT
GROUP_concat(child.child), p1.parent, p2.parent FROM child Inner Join parents AS p1 ON p1.id_part = child.f_name Inner Join parents AS p2 ON p2.id_part = child.m_name GROUP BY p1.parent, p2.parent
Result
Upvotes: 1
Reputation: 115510
SELECT
Parents
, GROUP_CONCAT(name ORDER BY name) AS Children
FROM
( SELECT
GROUP_CONCAT(p.id_parent ORDER BY p.name) AS parents_ids
, GROUP_CONCAT(p.name ORDER BY p.name) AS Parents
, pc.id_child
, c.name
FROM parents p
JOIN parents_children pc USING(id_parent)
JOIN children c USING(id_child)
GROUP BY pc.id_child
) AS tmp
GROUP BY parents_ids ;
You can test it in: SQL-Fiddle
Upvotes: 1
Reputation: 58444
There are two solutions for this issue:
On php side iterate through the array and create an array where key of [$parent_1 . '|' . $parent2]
contains another array with children.
On SQL end of thing do something similar to this:
SELECT
GROUP_CONCAT(Parents.name ORDER BY Parents.parents_id, '|') AS parents,
Children.name as child
FROM Children
LEFT JOIN CildrentParents USING( children_id )
LEFT JOIN Parents USING( parent_id )
GROUP BY Childrent.children_id
and then work with this dataset.
P.S. i don't see, how just adding DISTINCT
to the original query, would solve this ... maybe i am missing something here.
And what exactly is stopping you from using PHP to create an array, where each parent
key contains a list of children?
Upvotes: 0
Reputation: 2860
SELECT DISTINCT should limit them down to one instance of each entity in the parent table.
Upvotes: 2