所以,让我们试着让这个变得简单。 假设我有三张桌子(我将在这里发布感兴趣的有用属性):
DEVELOPERS( dev_id, ...)
COLLABORATIONS( activity_id, dev_id, ... )
ACTIVITY( activity_id, ...)
协作是一个表,用于将完成的所有活动链接到处理它们的开发人员(它的主键是activity_id, dev_id
对)。重要的是,在一个单独的Activity上可以至少有1个dev,但是它们的最大值是未定义的(没有限制)
我需要知道的是,并且我很难理解,所有对(并且只有一对)开发人员的dev_id
是如何从未合作的(也就是没有合作的元组)相同的activity_id和他们的dev_id)但是,他们两个都与(至少一个)相同的“第三开发者”在其他协作中合作
我需要得到一个行表,其中有两列包含满足要求的每对开发者。
请注意,我并不是要求只检查与两个开发人员合作的协作,而是检查其中的每一个。
我的第一个想法是先找到所有合作的开发人员,从所有开发人员列表中删除他们的dev_id(可能还有一个除外?)(所以我只有那些从未在自己内部合作过的人)并从那里开始。
有任何想法或建议吗?
添加澄清示例:
activity_id dev_id
1 2
1 3
1 5
2 1
2 3
3 1
3 4
3 2
所以这里例如dev 3和4从未一起工作,但两者都至少与另一个相同的开发人员(在这种情况下为dev 1和dev 2)
Dev 1和5从未一起工作,但两者都与至少另一个相同的dev(在这种情况下为dev 3和dev 2)合作
Dev 4和dev 5从未一起工作,但两者都与至少另一个相同的dev(在这种情况下为dev 2)合作
所以查询应该返回
devA devB
3 4
1 5
4 5
答案 0 :(得分:0)
我相信有人能够改进这一点,但我认为它有效(见fiddle):
SELECT DISTINCT
c.dev_id,
d.dev_id
FROM
COLLABORATIONS c,
DEVELOPERS d
WHERE
c.dev_id > d.dev_id AND
(
SELECT
ca.activity_id
FROM
COLLABORATIONS ca
WHERE
ca.dev_id = c.dev_id AND
ca.activity_id IN
(
SELECT
cb.activity_id
FROM
COLLABORATIONS cb
WHERE cb.dev_id = d.dev_id
)
LIMIT 1) IS NULL AND
(
SELECT
cc.dev_id
FROM
COLLABORATIONS cc
WHERE
cc.activity_id IN
(
SELECT
cd.activity_id
FROM
COLLABORATIONS cd
WHERE
cd.dev_id = c.dev_id) AND
cc.dev_id IN
(
SELECT
ce.dev_id
FROM
COLLABORATIONS ce
WHERE
ce.activity_id IN
(
SELECT
cf.activity_id
FROM
COLLABORATIONS cf
WHERE
cf.dev_id = d.dev_id)
)
LIMIT 1) IS NOT NULL
答案 1 :(得分:0)
这是非常简单的方法
SELECT DISTINCT a.dev_id, d.dev_id
FROM COLLABORATIONS AS a
JOIN COLLABORATIONS AS b ON a.activity_id = b.activity_id AND a.dev_id<>b.dev_id
JOIN COLLABORATIONS AS c ON b.dev_id = c.dev_id
JOIN COLLABORATIONS AS d ON c.activity_id = d.activity_id AND c.dev_id<>d.dev_id
WHERE a.dev_id<d.dev_id
EXCEPT
SELECT DISTINCT a.dev_id, b.dev_id
FROM COLLABORATIONS AS a
JOIN COLLABORATIONS AS b ON a.activity_id = b.activity_id AND a.dev_id<b.dev_id
ORDER BY 1, 2
通过第三人连接的所有对都需要减去所有直接对。由于mysql不支持EXCEPT,你必须更换它,我会把它留作练习。