1

我知道 SQL 的基础知识,但是对于一个项目,我需要执行以下操作,但我被阻止了。我有两张桌子:

ID | NAME 

和项目

ID | PersonID | ProjectID

在 Project 表中,相同的 ProjectID 可能在每个人的 4 条记录中出现一次。我想要一个列表,其中包含来自 Person 的所有名称以及他们在项目中一起工作的所有名称。

因此,如果我有某个人(即 ID 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 表的所有记录?

4

2 回答 2

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;

编辑:

这是思考问题的另一种方式(如果我的解释是正确的)。我不知道为什么我没有先朝这个方向走。您正在寻找在一个项目上一起工作的所有(不同的)人。从这样的列表中获取对是自联接。这导致以下查询:

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;

group_concat()如果您想将行放入逗号分隔的列表中,可以添加。)

于 2013-05-30T16:05:26.840 回答
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
于 2013-05-30T16:26:16.303 回答