繁体   English   中英

自我加入多对多的关系

[英]Self join many-to-many relationship

根据以下样本数据,假设朱莉(1)有朋友亚当,大卫,约翰(2,3,4)。 亚当(2)有朋友朱莉,大卫,约翰(1,3,4)。

ID  Name
1   Julie
2   Adam
3   David
4   John
5   Sam

这使得一个表内的自连接和多对多关系成为可能。

除了上述问题之外,Julie(1)还说Sam(5)是朋友,从技术上和实际上讲,Sam(5)现在也是Julie(1)的朋友。 这使得事情变得更加复杂,因为这种关系是双向的。

所以我想知道:

  1. 我该如何设计数据库?
  2. 如何进行将返回每个用户的所有朋友的查询?

谢谢!

示例数据:

PEOPLE

PERS_ID     PERS_NAME
1           Julie
2           Adam
3           David
4           John
5           Sam

FRIENDSHIPS

PERS_ID     FRIEND_ID
1           2
1           3
1           4
2           3
2           4

查询:

select people.pers_id    as person,
       people.pers_name  as person_name,
       peoplef.pers_id   as friend_id,
       peoplef.pers_name as friend_name
  from people
  join friendships
    on people.pers_id = friendships.pers_id
    or people.pers_id = friendships.friend_id
  join people peoplef
    on (peoplef.pers_id = friendships.pers_id and
       peoplef.pers_id <> people.pers_id)
    or (peoplef.pers_id = friendships.friend_id and
       peoplef.pers_id <> people.pers_id)
 order by 2, 4

SQL小提琴演示: http ://sqlfiddle.com/#!2/97b41/6/0

无论您是否在友谊表上记录两个方向,这都将有效。

非常赞同其他人。 你需要一个链接表。 我将提供更多细节..密钥和索引的一些示例以及您想要的查询(双向)。

    CREATE TABLE dbo.tblUser 
(
    ID int identity(0,1),
    name varchar(20)
    CONSTRAINT PK_tblUser PRIMARY KEY (ID)
)

-- Many to many link table with FKs
CREATE TABLE dbo.tblFriend 
(
    ID1 int not null constraint FK_tblUser_ID1 foreign key references dbo.tblUser(ID), 
    ID2 int not null constraint FK_tblUser_ID2 foreign key references dbo.tblUser(ID)
    CONSTRAINT PK_tblFriend PRIMARY KEY (ID1, ID2)
)

-- Add index (So you can get an index seek if using ID2)
CREATE INDEX IX_tblFriend_ID2 ON dbo.tblFriend (ID2)

-- Test data
INSERT INTO dbo.tblUser(name)
VALUES ('Julie'),('Adam'),('David'),('John'),('Sam');

Insert INTO dbo.tblFriend (ID1, ID2) 
values(0, 1),(2, 0)


-- Get bi-directional friend to friend relationships
SELECT U1.Name as 'User1', U2.Name as 'User2' FROM dbo.tblFriend F 
    INNER JOIN dbo.tblUser U1 ON U1.ID = F.ID1
    INNER JOIN dbo.tblUser U2 ON U2.ID = F.ID2

UNION

SELECT U2.Name as 'User1', U1.Name as 'User2' FROM dbo.tblFriend F 
    INNER JOIN dbo.tblUser U1 ON U1.ID = F.ID1
    INNER JOIN dbo.tblUser U2 ON U2.ID = F.ID2

ORDER BY User1, User2

一种方法可能是您创建存储人员和朋友ID的第二个表。 在此方案中,请考虑以下表格。

CREATE TABLE User 
    (
     id int auto_increment primary key, 
     name varchar(20)
    );

CREATE TABLE Friend 
    (
     user_id int , 
     friend_id int      
    );

INSERT INTO User
(name)
VALUES
('Julie'),
('Adam'),
('David'),
('John'),
('Sam');

Insert INTO Friend
(user_id, friend_id)
values(1, 5),
(3, 1);

现在,Friend表将存储user_id和他/她的friend_id。 要获取特定用户的朋友列表,您可以在这两列中的任意一列中搜索id匹配。 以下是示例查询。

-- Get Friends of Julie
select 1 AS user_id, IF(user_id = 1, friend_id, user_id) AS friend_id
FROM Friend
WHERE user_id=1 OR friend_id=1;

-- Get Friends of David
select 3 AS user_id, IF(user_id = 3, friend_id, user_id) AS friend_id
FROM Friend
WHERE user_id=3 OR friend_id=3

我希望你对此有所了解并且可以玩。

我试过你在查询中写的任何东西:

declare @table table  
(
  id int,
  name varchar(40)
)

insert into @table values
(1,   'Julie'),
(2,   'Adam'),
(3,   'David'),
(4,   'John'),
(5,   'Sam')

select

t1.name ,
t2.name as friend

from @table t1, @table t2 where t1.id <> t2.id
and t1.id in (1,2) and t2.id <> 5
order by t1.id

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM