仅显示一次数据

时间:2012-05-16 18:44:43

标签: php mysql

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

简短说明数据库的工作方式: 每个父母可以有一个或多个孩子,每个孩子可以有一个或多个父母 - 多对多的关系。我把它分为三个表 - 父母,孩子和父母,为了建立一对多的关系。然后我使用了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

4 个答案:

答案 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_keym_name),   KEY f_keyf_name),   CONSTRAINT f_key FOREIGN KEY(f_name)引用parentsid_part)ON更新级联上的DELCAD CASCADE,   CONSTRAINT m_key FOREIGN KEY(m_name)引用parentsid_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

结果

儿童的名字|父亲的名字|妈妈的名字

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

q,r |父亲2 |妈妈2

t,j |父亲3 |妈妈3

答案 3 :(得分:0)

此问题有两种解决方案:

  1. 在php端迭代数组并创建一个数组,其中[$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
    

    然后使用此数据集。

  3. P.S。我没有看到,如何将DISTINCT添加到原始查询中,可以解决这个问题......也许我在这里遗漏了一些东西。

    更新

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