SQL Server从两个表创建视图

时间:2018-02-13 19:08:32

标签: sql sql-server tsql join

我在SQL Server数据库中有两个表来跟踪社交网络。首先是看起来像

的朋友表
userId | friendId | acceptDate
==============================
   1   |     8    | 2018-01-20
   8   |     12   | 2017-11-20
   12  |     1    | 2017-12-18

所以每一对都是一个组合,顺序只取决于哪个用户发起了连接。

第二个表是一个包含用户信息的表

userId | name | email | ...
   1   | John  | john@example.com  | ...
   2   | Bill  | bill@example.com  | ...
   3   | Cathy | cathy@example.com | ...

我想创建一个视图,在那里我可以轻松地获取特定用户的朋友所需的数据,并且服务器端处理最少。所以基本上我想创建一个数据看起来像的视图:

userId | friendID | friendName | friendEmail | acceptDate | ....
   1   |     8    |  8's Name  |  8's Email  | 2018-01-20 |...
   1   |    12    |  12's Name |  12's Email | 2017-12-18 |...
   8   |    12    |  12's Name |  12's Email | 2017-11-20 |...
   8   |     1    |  1's Name  |  1's Email  | 2018-01-20 |...
  12   |     1    |  1's Name  |  1's Email  | 2017-12-18 |...
  12   |     8    |  8's Name  |  8's Email  | 2017-11-20 |...

基本上,它会在friends表中存在的每个友谊对中创建两行(一个在现有顺序中,一个翻转),并将从用户表中加入朋友的信息。通过这种方式,我可以简单地查询视图以找到我所有特定用户的朋友,并且它只返回该用户的朋友的行和他们的信息,并且我赢了。我必须做任何处理来解决问题。

非常感谢任何帮助。

谢谢!

4 个答案:

答案 0 :(得分:0)

由于您必须切换前两列中的所有数据,因此您需要将数量加倍。使用UNION ALL可能最容易。这样的事情应该非常接近。

select *
from
(
    select UserID
        , FriendID
        , FriendName = sot.name
    from SomeTable st
    join SomeOtherTable sot on sot.UserID = st.UserID

    UNION ALL

    select FriendID
        , UserID
        , FriendName = sot.name
    from SomeTable st
    join SomeOtherTable sot on sot.UserID = st.FriendID
) x
order by x.UserID
    , x.FriendID

答案 1 :(得分:0)

-- Friends I accepted 
select userid, f.userId friendID, f.name friendName, f.email friendEmail, friends.acceptDate
from users inner join friends on users.userId = friends.userId inner join users f on friends.friendId = f.Userid

union all
-- friends who accepted me. 
select userid, f.userId friendID, f.name friendName, f.email friendEmail, friends.acceptDate
from users inner join friends on users.userId = friends.friendID inner join users f on friends.userid = f.Userid

答案 2 :(得分:0)

这是一个有效的例子:

编辑,我已经添加了来自userID的电子邮件,并添加了union all以支持操作心,快乐的v-day。

declare @user as table (
    userID       int identity(1,1) not null primary key clustered
,   Name_        nvarchar(255) not null
,   EmailAddress nvarchar(255) not null
);

declare @duo as table (
    duoID   int identity(1,1) not null primary key clustered 
,   userID  int not null
,   loserID int not null
,   LoveDate date not null
);

insert into @user (name_, EmailAddress)

select 'bob', 'bob@example.com' union all
select 'tom', 'tom@example.com' union all
select 'nick', 'nick@example.com' union all
select 'Random', 'awesomesauce@example.com';

insert into @duo (userid, loserid, LoveDate)
select 1, 2, '2018-01-14' union all
select 1, 3, '2018-02-14' union all
select 1, 4, '2018-01-15' union all
select 2, 3, '2018-01-14' union all
select 2, 4, '2018-01-18' union all
select 3, 4, '2018-01-13';


select a.UserID
     , a.Name_ Person
     , a.EmailAddress
     , c.userID LoserID
     , c.Name_ Loser
     , c.EmailAddress 'Loser''s Email'
     , b.LoveDate
  from @user a
  join @duo b
    on a.userid = b.userid
  join @user c
    on b.loserid = c.userid

union all

select c.userID 
     , c.Name_ Person
     , c.EmailAddress
     , a.UserID LoserID
     , a.Name_ Loser
     , a.EmailAddress 'Loser''s Email'
     , b.LoveDate
  from @user a
  join @duo b
    on a.userid = b.userid
  join @user c
    on b.loserid = c.userid

答案 3 :(得分:0)

这可以通过JOIN来完成:

onCreate