我为日托中心的父母创建了一个联系人列表。现在我想在网页上显示它。到目前为止,它在技术上完美无缺,但它是我不满意的布局。
简短说明数据库的工作方式: 每个父母可以有一个或多个孩子,每个孩子可以有一个或多个父母 - 多对多的关系。我把它分为三个表 - 父母,孩子和父母,为了建立一对多的关系。然后我使用了JOIN,一切都显示得很好。但是,因为它显示了每个实体,所以它变得杂乱无章,以便在网页上显示它。我将用一个例子来解释:
家庭1:马克和爱丽丝威尔逊有两个孩子,约翰和比尔 家庭2:Peter和Jessica Robertson有一个孩子,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
-------------------------------
有没有什么好方法可以获得所需的布局?
好的,所以现在我已经到了让这个工作在一个列中,这取决于我如何使用GROUP_CONCAT:
代码:
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;
结果:
Parents Children
-----------------------------------------------
Mark Wilson, Alice Wilson Bill Wilson
Mark Wilson, Alice Wilson John Wilson
Peter Robertson, Jessica Robertson Lisa Robertson
同样,如果我GROUP_CONCAT children.name和GROUP BY pc.id_child而得到:
Parents Children
------------------------------------------
Mark Wilson Bill Wilson, John Wilson
Alice Wilson Bill Wilson, John Wilson
Peter Robertson Lisa Robertson
Jessica Robertson Lisa Robertson
我真的想要这些组合,结果如下:
Parents Children
----------------------------------------------------
Mark Wilson, Alice Wilson Bill Wilson, John Wilson
Peter Robertson, Jessica Robertson Lisa Robertson
答案 0 :(得分:2)
SELECT DISTINCT应将它们限制为父表中每个实体的一个实例。
答案 1 :(得分:1)
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 ;
您可以在SQL-Fiddle
中进行测试答案 2 :(得分:1)
表父母:
CREATE TABLE `parents` (
id_part
int(11)NOT NULL AUTO_INCREMENT,
parent
varchar(60)DEFAULT NULL,
主要关键(id_part
)
)ENGINE = InnoDB AUTO_INCREMENT = 7 DEFAULT CHARSET = utf8
表孩子:
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
)引用parents
(id_part
)ON更新级联上的DELCAD CASCADE,
CONSTRAINT m_key
FOREIGN KEY(m_name
)引用parents
(id_part
)ON DELETE CASCADE ON UPDATE CASCADE
)ENGINE = InnoDB AUTO_INCREMENT = 8 DEFAULT CHARSET = utf8
查询加入两个表
SELECT DISTINCT
GROUP_CONCAT(child.child), p1.parent, p2.parent 从 儿童 内部加入父项AS p1 ON p1.id_part = child.f_name 内部加入父项AS p2 ON p2.id_part = child.m_name 通过...分组 p1.parent, p2.parent
结果
答案 3 :(得分:0)
此问题有两种解决方案:
在php端迭代数组并创建一个数组,其中[$parent_1 . '|' . $parent2]
的键包含另一个带子项的数组。
在SQL结尾处做类似的事情:
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
然后使用此数据集。
P.S。我没有看到,如何将DISTINCT
添加到原始查询中,可以解决这个问题......也许我在这里遗漏了一些东西。
究竟是什么阻止你使用PHP创建一个数组,其中每个parent
键包含一个子列表?