[英]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”帐户,并为您添加了说明。
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.