2013-05-30 2 views
1

Я знаю основы SQL, но для проекта мне нужно сделать следующее, и я заблокирован. У меня есть две таблицы:sql получить связанные записи на основе второй таблицы

Person

ID | NAME 

и проекта

ID | PersonID | ProjectID 

В таблице проекта может быть, что же ProjectID находится в 4-х записей один раз для каждого человека. Мне нужен список со всеми именами Person и всеми именами, с которыми они работали вместе в Project.

Так что, если у меня есть определенное лицо (т.е. 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 таблицы?

+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; 

EDIT:

Вот еще один способ думать о проблеме (если моя интерпретация верно). Я не уверен, почему я не пошел в этом направлении. Вы ищете всех (отдельных) пар людей, которые работали вместе над проектом. Получение пар из такого списка - это самосоединение. Это приводит к следующему запросу: (. Вы можете добавить 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

wow это отлично работает, так что я думаю, что это так. Большое спасибо :) – 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

новая версия для пар - о ... просто видел: это то же самое, что и @ gordon's :) – Ochi

Смежные вопросы