sql - 如何使用 JOIN 而不是 UNION 来计算 "A OR B"的邻居?

标签 sql sql-server-2008

以下查询计算图中两个节点的公共(public)邻居:

    DECLARE @monthly_connections_test TABLE (
  calling_party VARCHAR(50)
  , called_party VARCHAR(50))

INSERT INTO @monthly_connections_test
          SELECT 'z1', 'z2'
UNION ALL SELECT 'z1', 'z3'
UNION ALL SELECT 'z1', 'z4'
UNION ALL SELECT 'z1', 'z5'
UNION ALL SELECT 'z1', 'z6'
UNION ALL SELECT 'z2', 'z1'
UNION ALL SELECT 'z2', 'z4'
UNION ALL SELECT 'z2', 'z5'
UNION ALL SELECT 'z2', 'z7'
UNION ALL SELECT 'z3', 'z1'
UNION ALL SELECT 'z4', 'z7'
UNION ALL SELECT 'z5', 'z1'
UNION ALL SELECT 'z5', 'z2'
UNION ALL SELECT 'z7', 'z4'
UNION ALL SELECT 'z7', 'z2'

SELECT     monthly_connections_test.calling_party AS user1, monthly_connections_test_1.calling_party AS user2, COUNT(*) AS calling_calling, 0 AS calling_called, 
                      0 AS called_calling, 0 AS called_called, 0 AS both_directions
FROM         @monthly_connections_test AS monthly_connections_test INNER JOIN
                      @monthly_connections_test AS monthly_connections_test_1 ON 
                      monthly_connections_test.called_party = monthly_connections_test_1.called_party AND 
                      monthly_connections_test.calling_party < monthly_connections_test_1.calling_party
GROUP BY monthly_connections_test.calling_party, monthly_connections_test_1.calling_party

对于下图 alt text

它返回由 user1 和 user2 调用的公共(public)邻居的数量,例如,由 z1 和 z2 调用的邻居的数量,它返回 2,因为同时调用 z4 和 z5。

我想计算的另一件事是由 user1 或 user2 调用的两个节点(用户)的所有邻居的数量,因此例如对于 (z1, z2) 对,查询应返回 5 (用户 z1 调用z2、z3、z4、z5、z6 和用户 z2 调用 z1、z4、z5、z7 - z1 和 z2 之间的连接必须被排除,因为 (z1, z2) 是观察到的对,并且 (z3, z4, z5, z6) U (z4, z5, z7) 为 5)。

有人知道如何修改/创建上述逻辑的连接查询吗?

谢谢!

最佳答案

@Martin 的答案是正确的。他是个天才。

马丁加油!

更正

如果针对我给出的双向解决方案运行,他的答案只需进行 1 个小修改即可。否则结果不正确。

所以你的答案是他的和我的:)

完整的解决方案:

DECLARE @T1 TABLE (calling_party VARCHAR(50), called_party VARCHAR(50))

INSERT  INTO @T1
SELECT  *
FROM    dbo.monthly_connections_test

INSERT  INTO @T1
SELECT  *
FROM    (
        SELECT  called_party AS calling_party, calling_party AS called_party
        FROM    dbo.monthly_connections_test AS T2
        WHERE   T2.called_party < T2.calling_party
        ) T2
WHERE   NOT EXISTS (
        SELECT *
        FROM    monthly_connections_test
        WHERE   calling_party = T2.calling_party and called_party = T2.called_party
)

select u1, u2, count(called_party) called_parties 
from (
select distinct u1, u2, called_party from 
(
        select a1.calling_party u1, a2.calling_party u2 from 
        (select calling_party from @T1 group by calling_party) a1,
        (select calling_party from @T1 group by calling_party) a2
) pairs,
 @T1 AS T
where
(u1 <> u2) and 
((u1 = t.calling_party and u2 <> t.called_party) or
(u2 = t.calling_party and u1 <> t.called_party))
) res
group by u1, u2
order by u1, u2

关于sql - 如何使用 JOIN 而不是 UNION 来计算 "A OR B"的邻居?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4296196/

相关文章:

sql - 计算直到某个日期的唯一组合 - 每月

sql - 具有多个左外连接的 Postgres Create Table As Select 查询产生重复数据

sql - 联合和联合所有

sql-server-2008 - 什么是SQL SERVER 2008中的SID?

php - 更新先前使用 MYSQL 和 PHP 选择的一组行

sql - 如何使用SQL计算表中的唯一记录并获取这些唯一记录的数量?

sql-server - 如何优雅地写一个 SQL ORDER BY(在内联查询中无效),但聚合 GROUP BY 需要?

asp.net - 使用外键列进行 SQL 全文搜索

.net - SQL Server 中的列级压缩

sql-server-2008 - 使用文件流存储图像和缩略图是一个好主意吗?