Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL中的对计数_Sql_Oracle - Fatal编程技术网

SQL中的对计数

SQL中的对计数,sql,oracle,Sql,Oracle,我有一个包含2个表的数据库: 用户用户id主键和朋友 friends表被组织成两列friend1、friend2,这两列都包含用户ID作为引用用户的外键。在每个朋友对中,friend1的用户id小于Friend2的用户id 我试图找到一个不是朋友但分享最多朋友的用户列表 我在两个单独的查询中成功地做到了这一点: 用户u1和u2的共享好友数 select count(*) from ((select friend1 from friends where friend2 = u1 UNIO

我有一个包含2个表的数据库:

用户用户id主键和朋友

friends表被组织成两列friend1、friend2,这两列都包含用户ID作为引用用户的外键。在每个朋友对中,friend1的用户id小于Friend2的用户id

我试图找到一个不是朋友但分享最多朋友的用户列表

我在两个单独的查询中成功地做到了这一点:

用户u1和u2的共享好友数

select count(*)
from 
    ((select friend1 from friends where friend2 = u1 UNION 
    select friend2 from friends where friend1 = u1)
    INTERSECT
    (select friend1 from friends where friend2 = u2 UNION 
    select friend2 from friends where friend1 = u2))
;
非朋友的所有用户\u id->用户\u id对的集合:

select distinct
    u1.user_id as friend1,
    u2.user_id as friend2
from
    users u1,
    users u2
where
    u1.user_id < u2.user_id
minus
select friend1, friend2
from friends order by friend1;

因此,user1这应该让您开始学习,但它是Microsoft SQL,尽管非常通用

select a1.friend1 as User1,
       a2.friend1 as user2,
       count( distinct a1.friend2) as Shared_Friends
from friends a1 
join (select distinct friend1,friend2 from friends a2) a2 
       on a1.friend2=a2.friend2
left join friends a3 on a3.friend1=a1.friend1 and a3.friend2 = a2.friend1
where (a1.friend1=1 and a2.friend1=8) and a3.friend1 is null
group by a1.friend1,a2.friend1

CTE只是提供一些样本数据

With Users As
    (
    Select 1 As UserId, 'Alice' As Name
    Union All Select 2, 'Bob'
    Union All Select 3, 'Caroline'
    Union All Select 4, 'Doug'
    )
    , Friends As
    (
    Select 1 As Friend1, 2 As Friend2
    Union All Select 2, 1
    Union All Select 2, 3
    Union All Select 2, 4
    Union All Select 3, 1
    Union All Select 3, 4
    )
    , UserFriends As
    (
    Select U1.UserId
        , Case
            When F1.Friend1 = U1.UserId Then F1.Friend2
            Else F1.Friend1
            End As Friend
    From Users As U1
        Join Friends As F1
            On U1.UserId In(F1.Friend1,F1.Friend2)
    Group By U1.UserId
        , Case
            When F1.Friend1 = U1.UserId Then F1.Friend2
            Else F1.Friend1
            End     
    )
Select U1.Name, U2.Name
    , Count(*) As MutualFriendCount
    , Group_Concat(F.Name) As SharedFriends
From UserFriends As UF1
    Join UserFriends As UF2
        On UF2.Friend = UF1.Friend
    Join Users As U1
        On U1.UserId = UF1.UserId
    Join Users As U2
        On U2.UserId = UF2.UserId
    Join Users As F
        On F.UserId = UF1.Friend
            And F.UserId = UF2.Friend
Where UF1.UserId <> UF2.UserId
    And Not Exists  (
                    Select 1
                    From UserFriends As F3
                    Where F3.UserId = UF1.UserId
                        And F3.Friend = UF2.UserId
                    )
Group By U1.Name, U2.Name
Order By U1.Name, U2.Name

我不确定我是否明白这是在做什么。共享的朋友必须在User1和User2之间,而不仅仅是user1a1.friend2的朋友,除非我在回复中误解了什么,这似乎是它所暗示的。
With Users As
    (
    Select 1 As UserId, 'Alice' As Name
    Union All Select 2, 'Bob'
    Union All Select 3, 'Caroline'
    Union All Select 4, 'Doug'
    )
    , Friends As
    (
    Select 1 As Friend1, 2 As Friend2
    Union All Select 2, 1
    Union All Select 2, 3
    Union All Select 2, 4
    Union All Select 3, 1
    Union All Select 3, 4
    )
    , UserFriends As
    (
    Select U1.UserId
        , Case
            When F1.Friend1 = U1.UserId Then F1.Friend2
            Else F1.Friend1
            End As Friend
    From Users As U1
        Join Friends As F1
            On U1.UserId In(F1.Friend1,F1.Friend2)
    Group By U1.UserId
        , Case
            When F1.Friend1 = U1.UserId Then F1.Friend2
            Else F1.Friend1
            End     
    )
Select U1.Name, U2.Name
    , Count(*) As MutualFriendCount
    , Group_Concat(F.Name) As SharedFriends
From UserFriends As UF1
    Join UserFriends As UF2
        On UF2.Friend = UF1.Friend
    Join Users As U1
        On U1.UserId = UF1.UserId
    Join Users As U2
        On U2.UserId = UF2.UserId
    Join Users As F
        On F.UserId = UF1.Friend
            And F.UserId = UF2.Friend
Where UF1.UserId <> UF2.UserId
    And Not Exists  (
                    Select 1
                    From UserFriends As F3
                    Where F3.UserId = UF1.UserId
                        And F3.Friend = UF2.UserId
                    )
Group By U1.Name, U2.Name
Order By U1.Name, U2.Name