Mysql Query查找放置相同订单的朋友的朋友和朋友

时间:2016-09-14 20:38:25

标签: mysql sql social-networking

我有3个表格如下

用户

- id integer primary_key
- user_name 

朋友

- id autoincrement primary_key 
- user1 integer foreign_key(User.id)
- user2 integer foreign_key(User.id)

订单

- id integer primary_key autoincrement
- product_id integer 
- by_user foreign_key(User.id) 

我已获得用户的ID和product_id。

我必须写一个查询,这将给我这个订阅同一产品的用户的所有朋友以及订购相同产品的所有朋友的朋友。

我如何在mysql中编写这样的查询?

样本数据说明

用户

id    |   name
------------------
1     |   peter   
2     |   sam
3     |   xang
4     |   aisha
5     |   rita
6     |   mojo
7     |   raj
8     |   ben

朋友

(如果id为1和2的用户是朋友,则可以将其存储为user1 = 1,user2 = 2或user1 = 2,user2 = 1,均表示用户之间的关系)

id          user1        user2 
---------------------------------------------
1      |     1       |     2      
2      |     2       |     3      
3      |     3       |     4      
4      |     4       |     2      
5      |     5       |     6      
6      |     6       |     8      
7      |     8       |     1   

订单

id         product_id           by_user 
-----------------------------------------------
1      |    100        |          2        
2      |    100        |          3       
3      |    100        |          4       
4      |    100        |          5       
5      |    100        |          7       
6      |    101        |          5       
7      |    102        |          6       
8      |    103        |          1          

所以提供的数据是:

用户= 1,产品= 100

我们需要做什么:

id = 1的用户的朋友是[2,8](我们称之为f1)

f1中的用户朋友= [1,3,4,6](让我们称之为f2)

现在从订单表中给出userid,该订单表为product_id = 100下订单,并且用户ID为f1 + f2,即[2,8,1,3,4,6]

所以这里的结果应该是:

[2,3,4]

2 个答案:

答案 0 :(得分:0)

SELECT DISTINCT u.id, u.name
FROM
    Friends f1
    INNER JOIN Friends f2
    ON f1.user1 = f2.user1
    OR f1.user1 = f2.user2
    OR f1.user2 = f2.user1
    OR f1.user2 = f2.user2
    INNER JOIN Orders o
    ON (f1.user1 = o.by_user
    OR f1.user2 = o.by_user
    OR f2.user1 = o.by_user
    OR f2.user2 = o.by_user)
    AND o.product_id = 100
    INNER JOIN Users u
    ON o.by_user = u.id
WHERE   
    (f1.user1 = 1
    OR f1.user2 = 1)

此答案已更新为“朋友之友”并为您添加说明。

  • 在“朋友”表中查询包含用户1的任何记录,该记录将为您提供用户1以及他们的直接朋友。
  • 添加一个SELF JOIN到Friends表,其中包含user1 = user1,2到2 1到2 2到1的所有组合作为OR以获取所有朋友的朋友
  • 获取与您现有的4个用户列的任意组合相关的所有订单,并按product_id = 100
  • 限制结果
  • 您现在有重复的结果,因此请选择DISTINCT以获得每个用户1条记录。

答案 1 :(得分:0)

这应该是不言自明的,但只是为了使其更清晰:创建视图以一步一步解决问题,并使用UNION关键字加入不同程度的友谊。

DROP TABLE IF EXISTS Users;
CREATE TABLE Users (
    id INTEGER PRIMARY KEY,
    name NVARCHAR(50)
);

DROP TABLE IF EXISTS Friends;
CREATE TABLE Friends (
  user1 INTEGER,
  user2 INTEGER,
  FOREIGN KEY (user1) REFERENCES Users(id),
  FOREIGN KEY (user2) REFERENCES Users(id)
  );

DROP TABLE IF EXISTS Orders;
CREATE TABLE Orders (
  id INTEGER PRIMARY KEY,
  by_user INTEGER,
  FOREIGN KEY (by_user) REFERENCES Users(id) 
);

INSERT INTO Users (id,name) VALUES (1,"a"),(2,"b"),(3,"c"),(4,"d"),(5,"e"),(6,"f");

INSERT INTO Friends (user1,user2) VALUES (1,2),(2,1),(2,3),(3,2);

INSERT INTO Orders (id,by_user) VALUES(1,1);

DROP VIEW IF EXISTS FirstOrderFriends;
CREATE VIEW FirstOrderFriends AS
    SELECT DISTINCT Users.id AS id, f1.user2 AS friend1
        FROM Users 
            LEFT JOIN Friends AS f1 ON f1.user1 = Users.id;

DROP VIEW IF EXISTS SecondOrderFriends;
CREATE VIEW SecondOrderFriends AS
    SELECT DISTINCT Users.id AS id, f2.user2 AS friend2
        FROM Users 
            LEFT JOIN Friends AS f1 ON f1.user1 = Users.id  
            LEFT JOIN Friends As f2 ON f2.user1 = f1.user2;

DROP VIEW IF EXISTS FirstAndSecondOrderFriends;
CREATE VIEW FirstAndSecondOrderFriends AS
    SELECT DISTINCT * FROM (
            SELECT * FROM FirstOrderFriends
        UNION
            SELECT * FROM SecondOrderFriends
    );

SELECT * 
    FROM Users LEFT JOIN FirstAndSecondOrderFriends 
        ON Users.id = FirstAndSecondOrderFriends.id
    WHERE Users.id = 1;

我只是使用WHERE Users.id = 1;加入ORDERS表作为练习留给学生。