2013-05-30 44 views
1

我知道SQL的基础知识,但对于一个项目,我需要执行以下操作并将其阻止。 我有两个表:sql根据第二个表检索相关记录

ID | NAME 

和项目

ID | PersonID | ProjectID 

在项目表可能是同一个专案编号是4条记录一次为每个人。 我想要一个包含Person中所有名称的列表以及他们在一个Project中一起工作的所有名称。

所以,如果我有一定的人(即编号73571),我已经拿出来:

SELECT DISTINCT person.name 
FROM person INNER JOIN project on person.id=project.personid 
WHERE project.id IN (
    SELECT id FROM project WHERE id=73571) 
ORDER BY person.name; 

我如何能做到这一点,为Person表的所有记录工作?

+1

你能否提供一些示例输出?当一个项目有很多人并且一个人有很多项目时,输出应该是什么样子? –

+0

喜欢的东西: PERSON1 - Coworker1 PERSON1 - Coworker2 PERSON2 - ... – serkef

+0

我猜'WHERE ID = 73571'应该是'WHERE PERSONID = 73571' –

回答

0

这是一个想法。来自个人的姓名和所有与他们一起工作过的人的逗号分隔列表如何?这里是MySQL中的语法:

SELECT pp.p1, pp.p1.name, group_concat(distinct p2.name) 
FROM (select p1.id as p1, p1.name as p1name, p2.id as p2, p2.name as p2name 
     from person p1 cross join 
      person p2 
     where p1.id <> p2.id 
    ) pp join 
    project pr1 
    on pr1.personid = pp.p1 join 
    project pr2 
    on pr2.personid = pp.p2 and 
     pr2.id = pr1.id 
group by pp.p1, pp.p1name; 

这个想法从所有人对的主列表开始。然后,它加入第一个人的所有项目,以及第二个人的所有匹配项目。这些连接在一起,使用group concat

如果你是幸福的成对列表,这里是在SQL Server中运行的例子:

with person as (
     select 1 as id, 'a' as name union all 
     select 2, 'b' union all 
     select 3, 'c' union all 
     select 4, 'd' union all 
     select 5, 'e' 
    ), 
    project as (
     select 1 as id, 1 as personid union all 
     select 1 as id, 2 as personid union all 
     select 1 as id, 3 union all 
     select 2, 4 union all 
     select 2, 5 union all 
     select 3, 1 union all 
     select 3, 5 
    ) 
SELECT distinct pp.p1name, pp.p2name 
FROM (select p1.id as p1, p1.name as p1name, p2.id as p2, p2.name as p2name 
     from person p1 cross join 
      person p2 
     where p1.id <> p2.id 
    ) pp join 
    project pr1 
    on pr1.personid = pp.p1 join 
    project pr2 
    on pr2.personid = pp.p2 and 
     pr2.id = pr1.id; 

编辑:

这里是思考这个问题的另一种方式(如果我的解释是正确的)。我不知道为什么我没有先走这个方向。您正在寻找所有(不同的)在一个项目上一起工作的人。从这样的列表中获得配对是一种自我连接。这导致下面的查询:(您可以添加group_concat()如果你喜欢把行到一个逗号分隔的列表)

SELECT distinct p1.name, p2.name 
FROM project pr1 join 
    project pr2 
    on pr1.id = pr2.id and 
     pr1.personid <> pr2.personid join 
    person p1 
    on pr1.personid = p1.id join 
    person p2 
    on pr2.personid = p2.id; 

+0

感谢您的回答。我需要一段时间才能尝试,我会发布。 – serkef

+0

它变长了,我想这会花更长的时间。我的桌子有几十万行。 – serkef

+0

哇这个作品很棒,我猜@Ochi也是。非常感谢:) – serkef

0

简单的查询

select pro.projectid 
     ,per.name 
     ,trim(BOTH ',' FROM replace(GROUP_CONCAT(per.name SEPARATOR ','), per.name, '')) as coworkers 
from person as per, 
    project as pro 
where per.id = pro.personid 
group by pro.projectid 

projectid  name   coworkers 
1    person1  person2,person3,person4 
2    person2  person4 
3    person3  person4,person5 

-- for pairs 
    SELECT pro.projectid, per.name, co.name 
    FROM project pro 
     LEFT JOIN project pro2 on (pro.projectid = pro2.projectid and pro.personid <> pro2.personid) 
     LEFT JOIN person per on pro.personid = per.id 
     LEFT JOIN person co on pro2.personid = co.id 
ORDER BY pro.projectid ASC, per.name ASC, co.name ASC 
+0

这工作顺利和快速。我怎样才能让结果像person1-coworker1,person1-coworker2,每个都在不同的行中? – serkef

+0

对新版本 - 哦...只是看到它:它是一样的@戈登的:) – Ochi

相关问题