1

我为日托中心的父母创建了一个联系人列表。现在我想在网页上显示它。到目前为止,它在技术上运行完美,但它的布局让我不满意。

我的数据库如何工作的简短说明:每个父母可以有一个或多个孩子,每个孩子可以有一个或多个父母 - 多对多关系。为了建立一对多的关系,我将其分解为三张表 - parents、children 和 parent_children。然后我使用了 JOIN 并且一切都显示得很好。但是,由于它显示了每个实体,因此在网页上显示它会变得相当混乱。我会用一个例子来解释:

家庭 1:马克和爱丽丝威尔逊有两个孩子,约翰和比尔。
家庭 2:彼得和杰西卡罗伯逊有一个孩子,丽莎。

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
4

4 回答 4

2

SELECT DISTINCT 应​​该将它们限制为父表中每个实体的一个实例。

于 2012-05-16T18:55:28.673 回答
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

于 2012-05-18T23:31:47.373 回答
1

表父母:

CREATE TABLE `parents` (

id_partint(11) NOT NULL AUTO_INCREMENT, parentvarchar(60) DEFAULT NULL, PRIMARY KEY ( id_part)) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8

表孩子:

CREATE TABLE `child` (

id_childint(11) NOT NULL AUTO_INCREMENT, childvarchar(60) DEFAULT NULL, f_nameint(11) DEFAULT NULL, m_nameint(11) DEFAULT NULL, PRIMARY KEY ( id_child), KEY m_key( m_name), KEY f_key( f_name), CONSTRAINT f_keyFOREIGN KEY ( f_name) 参考parents( id_part) ON DELETE CASCADE ON UPDATE CASCADE, 约束外m_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 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。父母

结果

孩子的名字 | 父亲的名字| 母亲的名字

x,y,z | 父亲 1 | 妈妈 1

q,r | 父亲2 | 妈妈 2

t,j | 父亲3 | 母亲 3

于 2012-05-19T00:15:07.060 回答
0

这个问题有两种解决方案:

  1. 在 php 端遍历数组并创建一个数组,其中 key of
    [$parent_1 . '|' . $parent2]包含另一个带有子元素的数组。

  2. 在 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
    

    然后使用这个数据集。

PS我不明白,添加DISTINCT到原始查询中如何解决这个问题......也许我在这里遗漏了一些东西。

更新

究竟是什么阻止您使用 PHP 创建一个数组,其中每个parent键都包含一个子列表?

于 2012-05-16T19:03:50.837 回答