有些人帮助查询第三范式

时间:2012-03-20 00:45:26

标签: mysql database relational-database

我有三张桌子。一个是人,第二个是会议,第三个是出席(将人与会议联系起来)。详细说明,表格如下:

CREATE TABLE IF NOT EXISTS `people` (
  `id` int(255) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `icon` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;


CREATE TABLE IF NOT EXISTS `attend` (
  `people_id` int(255) NOT NULL,
  `meeting_id` int(255) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


CREATE TABLE IF NOT EXISTS `meeting` (
  `id` int(255) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;

我无法理解每个人所需要的SQL并列出他们遇到过的所有人。

我只能通过SQL

了解如何向一个方向攀爬
SELECT people.name, meeting.id FROM people LEFT JOIN attend ON people_id = people.id LEFT JOIN meeting ON meeting_id = meeting.id

非常感谢帮助解释。

3 个答案:

答案 0 :(得分:3)

您的桌面设计很好 - 当您以这种方式存储信息时,您将能够做任何您想做的事。

由于您之间存在互惠关系,因此除非您采取措施删除初始报告,否则您的初始报告将会有冗余。我的意思是,如果弗雷德在第1次会议上遇见玛丽,那么玛丽在同一次会议上遇见弗雷德。因此,下面的第一个解决方案会列出每个人两次 - 但如果您希望能够在您的人员列表中找到任何人并列出他们遇到的人,那么它很有用:

SELECT  distinct p1.name, 'met', p2.name, 'at', a1.meeting_id
FROM people as p1
    JOIN attend as a1 on a1.people_id = p1.id
    JOIN attend as a2 on a2.meeting_id = a1.meeting_id
    JOIN people as p2 on p2.id = a2.people_id
where p1.id <> p2.id
order by a1.meeting_id;

+------+-----+------+----+------------+
| name | met | name | at | meeting_id |
+------+-----+------+----+------------+
| Mary | met | Fred | at |          1 |
| Fred | met | Mary | at |          1 |
| Eric | met | Mary | at |          2 |
| Mary | met | Eric | at |          2 |
+------+-----+------+----+------------+

你明白我两次列出每个人的意思。如果你按p1.name或p2.name排序,你就会把人们聚在一起,这样“Mary”遇到的每个人都会在一起。

但您可以做其他事情,具体取决于使用您的查询的程序如何运作。

SELECT p.name, (SELECT group_concat(name) 
    FROM people as p1 
    JOIN attend as a1 on a1.people_id = p1.id
    JOIN attend as a2 on a2.meeting_id = a1.meeting_id
    WHERE a2.people_id = p.id
      AND p.id <> p1.id)
FROM people as p
ORDER by p.name;

+------+-----------+
| name | People    |
+------+-----------+
| Eric | Mary      |
| Fred | Mary      |
| Mary | Fred,Eric |
+------+-----------+

这效率较低(对您而言可能或不重要),但您会得到每个与他们相遇的人的列表。您可以展开该查询以列出他们遇到的会议等。

答案 1 :(得分:1)

select distinct p1.name, p2.name
from people p1, people p2, attend a1, attend a2, meeting m
where p1.id = a1.people_id
  and p2.id = a2.people_id
  and a1.meeting_id = m.id
  and a2.meeting_id = m.id
  and p1.id <> p2.id

或绕过会议桌:

select distinct p1.name, p2.name
from people p1, people p2, attend a1, attend a2
where p1.id = a1.people_id
  and p2.id = a2.people_id
  and a1.meeting_id = a2.meeting_id
  and p1.id <> p2.id

答案 2 :(得分:0)

请尝试以下

select p1.name as name1, p2.name as name2
from attend a1
inner join attend a2
  on a2.meeting_id = a1.meeting_id
  and a2.people_id > a1.people_id
inner join people p1
  on p1.id = a1.people_id
inner join people p2
  on p2.id = a2.people_id

在上面,我们使用内部联接来获取我们想要的字段并使用a2.people_id&gt; a1.people_id避免列出两次相同的metting