简体   繁体   English

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

[英]Mysql Query to find friends and friends of friends who placed same order

I have 3 tables as below 我有3张桌子如下

User 用户

- id integer primary_key
- user_name 

Friends

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

Orders 命令

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

I have been provided with user's id and product_id . 已为我提供了用户ID和product_id。

I have to write a query which will give me all the friends of this user who placed order for same product along with all friends of friends of this user who placed order for same products . 我必须编写一个查询,该查询将给我该用户下同一个产品订单的所有朋友以及该用户下同一个产品订单的所有朋友。

How i can write such a query in mysql ? 我如何在mysql中编写这样的查询?


Explanation with sample data 样本数据说明

User 用户

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

Friends

(if user with id 1 and 2 are friends then it can be stored as user1 = 1 and user2 = 2 OR user1 = 2 and user2 = 1 , both means a relationship between users) (如果ID为1和2的用户是朋友,则可以将其存储为user1 = 1和user2 = 2 OR 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   

Orders 命令

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          

So Provided data is : 因此提供的数据是:

User = 1 and product = 100 用户= 1,产品= 100

What we have to do : 我们要做的是:

friends of user with id = 1 are [2,8] (lets call it f1) id = 1的用户的朋友为[2,8](将其称为f1)

friends of users in f1 are = [1,3,4,6] (lets call it f2) f1中用户的朋友是= [1,3,4,6](我们称它为f2)

Now give userid from order table who placed order for product_id = 100 and have user id in f1+f2 ie [2,8,1,3,4,6] 现在从订单表中给出下了product_id = 100的订单的用户ID,并在f1 + f2中拥有用户ID,即[2,8,1,3,4,6]

So here result should be : 所以这里的结果应该是:

[2,3,4] [2,3,4]

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)

This answer is updated to account for Friends of Friends and to add an explanation for you. 此答案已更新为“ Friends of Friends”帐户,并为您添加了说明。

  • Query the Friends table for any record that contains user 1 which will give you User 1 as well as their immediate friends. 在“朋友”表中查询包含用户1的任何记录,这些记录将为您提供用户1及其直接朋友。
  • Add a SELF JOIN to Friends table with all of the combinations of user1 = user1, 2 to 2 1 to 2 2 to 1 as OR to get all of the Fiends of Friends 将SELF JOIN添加到Friends表中,将user1 = user1,2 to 2 1 to 2 2 to 1的所有组合作为OR来获取所有Friends的朋友
  • Get all orders related to any combination of the 4 user columns you now have and limit the results by product_id = 100 获取与您现在拥有的4个用户列的任意组合相关的所有订单,并将结果限制为product_id = 100
  • You now have duplicate results so select DISTINCT to get 1 record per user. 现在,您有重复的结果,因此选择DISTINCT可为每个用户获得1条记录。

This should be pretty self-explanatory, but just to make it even more clear: Create views to tackle the problem one step at a time, and use the UNION keyword to join different degrees of friendship. 这应该是不言而喻的,但仅仅是为了使它更加清晰:创建视图以一次一步地解决问题,并使用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;

I am just using WHERE Users.id = 1; 我只是在使用WHERE Users.id = 1; joining the ORDERS table is left as an exercise to the student. 加入ORDERS表作为练习留给学生。

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

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