如何合并来自2个SQL表的行而不重复行?

时间:2010-06-23 19:57:41

标签: sql mysql join database rows

我想这个查询有点基础,我应该对SQL有更多的了解但是还没有做很多关于连接的事情,我想这是解决方案。

我所掌握的是一张人员表和一份工作角色表。一个人可以有多个工作,我希望有一组结果,每人一行包含他们的详细信息和工作角色。

下面是两个示例表(people和job_roles),因此您可以更轻松地理解这个问题。

 id |  name  |    email_address   |  phone_number
 1  |  paul  |  paul@example.com  |  123456
 2  |   bob  |  bob@example.com   |  567891
 3  |  bart  |  bart@example.com  |  987561

job_roles

 id  |  person_id  |     job_title   | department
  1  |      1      |     secretary   |    hr
  2  |      1      |     assistant   |   media
  3  |      2      |      manager    |    IT
  4  |      3      |  finance clerk  |  finance
  4  |      3      |      manager    |    IT

这样我就可以输出每个人及其角色

Name: paul
Email Address: paul@example.com
Phone: 123456
Job Roles: 
Secretary for HR department
Assistant for media department
_______
Name: bob
Email address: bob@example.com
Phone: 567891
Job roles:
Manager for IT department

那么我如何将每个人的信息(来自人员表)以及他们的工作细节(从job_roles表)提供给输出,就像上面的例子一样。我想这可能是某种方式将他们的工作和相关部门合并到一个可以拆分输出的工作列中,但也许有更好的方法,sql会是什么样子?

由于

如果它有任何区别,它将是一个mySQL数据库

4 个答案:

答案 0 :(得分:3)

它看起来像一个直接的联接:

SELECT p.*, j.*
  FROM People AS p INNER JOIN Roles AS r ON p.id = r.person_id
 ORDER BY p.name;

剩下的工作是格式化;最好通过报告包完成。


  

感谢您的快速回复,这似乎是一个良好的开端,但每个人都会获得多行(您必须想象这是一个表格,因为您似乎无法在评论中进行格式化):

id | Name | email_address    | phone_number | job_role  | department
 1 | paul | paul@example.com | 123456       | secretary | HR
 1 | paul | paul@example.com | 123456       | assistant | media
 2 | bob  | bob@example.com  | 567891       | manager   | IT
  

如果可能的话,我希望每个人理想地拥有一排所有的工作角色?

这取决于您的DBMS,但大多数可用的不支持RVAs - 关系值属性。你想要的是让结果的工作角色和部门部分像一个与用户相关联的表:

+----+------+------------------+--------------+------------------------+
| id | Name | email_address    | phone_number |   dept_role            |
+----+------+------------------+--------------+------------------------+
|    |      |                  |              | +--------------------+ |
|    |      |                  |              | | job_role   | dept  | |
|  1 | paul | paul@example.com | 123456       | | secretary  | HR    | |
|    |      |                  |              | | assistant  | media | |
|    |      |                  |              | +--------------------+ |
+----+------+------------------+--------------+------------------------+
|    |      |                  |              | +--------------------+ |
|    |      |                  |              | | job_role   | dept  | |
|  2 | bob  | bob@example.com  | 567891       | | manager    | IT    | |
|    |      |                  |              | +--------------------+ |
+----+------+------------------+--------------+------------------------+

这准确地代表了您想要的信息,但通常不是一种选择。

那么,接下来会发生什么取决于您的报告生成工具。使用我最熟悉的那个(Informix ACE,Informix SQL的一部分,可从IBM获得与Informix DBMS一起使用),您只需确保对数据进行排序,然后打印名称,电子邮件地址和电话号码在报告的“BEFORE GROUP OF id”部分,以及“ON EVERY ROW”部分,您将处理(打印)角色和部门信息。

将报告格式与数据检索操作分开通常是个好主意;除非您的DBMS具有帮助格式化所选数据的异常功能,否则这是必要的示例。


  

哦,亲爱的,听起来非常复杂,而不是我可以在PHP页面的mySQL数据库上轻松运行的东西?

RVA的东西 - 你说得对,不适合MySQL和PHP。

另一方面,有数百万个报告(意味着格式化为向用户呈现的查询的结果)大致相同。它们的技术术语是“Control-Break Report”,但基本思路并不难。

您保留上次处理的“id”号码的记录 - 您可以将其初始化为-1或0。 当前记录的ID号与前一个号码不同时,您有一个新用户,您需要为新用户启动一组新的输出行并打印姓名,电子邮件地址和电话号码(并更改最后一个)已处理的身份证号码当前记录具有相同的ID号时,您所做的只是处理作业角色和部门信息(而不是名称,电子邮件地址和电话号码)。当id号改变时发生'break'。只需一级控制,就不难了;如果你有4或5个级别,你必须做更多的工作,这就是为什么有报告包来处理它。

所以,这并不难 - 只需要一点关心。

答案 1 :(得分:2)

RE:

  

我希望SQL能做点什么   聪明并将行连接在一起   很好,所以我基本上有一份工作   列中包含那些人的工作。

你可以与

接近
SELECT  p.id, p.name, p.email_address, p.phone_number,
group_concat(concat(job_title, ' for ', department, ' department')  SEPARATOR '\n') AS JobRoles
FROM People AS p 
    INNER JOIN job_roles AS r ON p.id = r.person_id
GROUP BY p.id, p.name, p.email_address, p.phone_number
 ORDER BY p.name;

答案 2 :(得分:0)

按照您想要的方式进行操作意味着结果集数组可能具有无限列,这将非常混乱。例如,您可以将作业表连接10次并获得job1,job2,... job10。

我会做一次连接,然后使用PHP来检查名称ID是否从1行到下一行是相同的。

答案 3 :(得分:0)

一种方法可能是将外部连接到表中,然后使用

将它们加载到一个数组中
$people_array =array(); 
while($row1=mysql_fetch_assoc($extract1)){ 
$people_array[] = $row1;  
} 

然后循环使用

 for ($x=0;$x<=sizeof($people_array;) 
    {  
echo $people_array[$x][id]; 
echo $people_array[$x][name]; 

for($y=0;$y<=$number_of_roles;$y++) 
{ 
 echo $people_array[$x][email_address]; 
 echo $people_array[$x][phone_number]; 
    $x++; 
} 
     } 

您可能需要稍微使用查询和循环,但它应该按照您的要求进行操作。为了使其按上述方式工作,每个人都必须拥有相同数量的角色,但您可以填写你表中的空白