Experiment 5 SQL complex business query

The first level is to find the products with more than 20 purchases and less than 50 weights, and sort them in ascending order of product id

Task description
There is a product table ( goods) as follows, the fields are: product id, product name, product quality

+------+------+--------+
|   id | name | weight |
+------+------+--------+
|    1 | A1   |    100 |
|    2 | A2   |     20 |
|    3 | B3   |     29 |
|    4 | T1   |     60 |
|    5 | G2   |     33 |
|    6 | C0   |     55 |
+------+------+--------+

There is also a transaction table ( trans), the fields are: transaction id, product id, and the number of purchases of this product

+------+----------+-------+
|tran_id|       id | count |
+------+----------+-------+
|    1 |        3 |    10 |
|    2 |        1 |    44 |
|    3 |        6 |     9 |
|    4 |        1 |     2 |
|    5 |        2 |    65 |
|    6 |        5 |    23 |
|    7 |        3 |    20 |
|    8 |        2 |    16 |
|    9 |        4 |     5 |
|   10 |        1 |     3 |
+------+----------+-------+

Find the products purchased more than and 20less than the weight 50, and sort them in idascending order, such as:

+------+-------+
| id   | total |
+------+-------+
|    2 |    81 |
|    3 |    30 |
|    5 |    23 |
+------+-------+

Example 1
input:

CREATE TABLE goods (
  id int(11) NOT NULL,
  name varchar(10)  DEFAULT NULL,
  weight int(11) NOT NULL,
  PRIMARY KEY (id)
);
CREATE TABLE trans (
  tran_id int(11) NOT NULL,
  id int(11) NOT NULL,
  count int(11) NOT NULL,
  PRIMARY KEY (tran_id)
);
insert into goods values(1,'A1',100);
insert into goods values(2,'A2',20);
insert into goods values(3,'B3',29);
insert into goods values(4,'T1',60);
insert into goods values(5,'G2',33);
insert into goods values(6,'C0',55);
insert into trans values(1,3,10);
insert into trans values(2,1,44);
insert into trans values(3,6,9);
insert into trans values(4,1,2);
insert into trans values(5,2,65);
insert into trans values(6,5,23);
insert into trans values(7,3,20);
insert into trans values(8,2,16);
insert into trans values(9,4,5);
insert into trans values(10,1,3);

output:

id    total
2    81
3    30
5    23
SELECT goods.id,sum(count) as total 
FROM goods JOIN trans 
WHERE goods.id=trans.id 
AND weight<50 
GROUP BY goods.id 
HAVING total>20 
ORDER BY goods.id

Level 2 query to recommend music to the user whose user_id = 1 in the follow table.

Task description
Assume that there are several simplified data tables in the music database:
the following followtable, the first column is the person who follows id, the second column is the person who is followed id, and the primary key 2of this column isid

+---------+-------------+
| user_id | follower_id |
+---------+-------------+
|       1 |           2 |
|       1 |           4 |
|       2 |           3 |
+---------+-------------+

The first row of this table represents the users idwho 1follow the user for the second row of the table represents the users who follow the user for the third row idof the table represents the users who follow the user for the user2
id1id4
id2id3

Personal favorite music music_likestable, the first column is the user id, the second column is the favorite music id, the composition of this 2column idis the primary key

+---------+----------+
| user_id | music_id |
+---------+----------+
|       1 |       17 |
|       2 |       18 |
|       2 |       19 |
|       3 |       20 |
|       4 |       17 |
+---------+----------+

The first row of this table represents the music that the user idhas 1liked music_idfor ... The fifth row of this table represents the music that the user has liked for17
id4music_id17

Music musictable, the first column is music id, the second column is music name, idwhich is the primary key

+----+------------+
| id | music_name |
+----+------------+
| 17 | yueyawang  |
| 18 | kong       |
| 19 | MOM        |
| 20 | Sold Out   |
+----+------------+

Please write a MYSQLquery user_id = 1to recommend music to the people you follow. Don't recommend music that the user already likes, and sort it in musicascending music_nameorder. The results you return should not contain duplicates The above query results are as follows:

+------------+
| music_name |
+------------+
| kong       |
| MOM        |
+------------+

Example 1
input:

CREATE TABLE follow (
user_id int(4) NOT NULL,
follower_id int(4) NOT NULL,
PRIMARY KEY (user_id,follower_id));

CREATE TABLE music_likes (
user_id int(4) NOT NULL,
music_id int(4) NOT NULL,
PRIMARY KEY (user_id,music_id));

CREATE TABLE music (
id int(4) NOT NULL,
music_name varchar(32) NOT NULL,
PRIMARY KEY (id));

INSERT INTO follow VALUES(1,2);
INSERT INTO follow VALUES(1,4);
INSERT INTO follow VALUES(2,3);

INSERT INTO music_likes VALUES(1,17);
INSERT INTO music_likes VALUES(2,18);
INSERT INTO music_likes VALUES(2,19);
INSERT INTO music_likes VALUES(3,20);
INSERT INTO music_likes VALUES(4,17);

INSERT INTO music VALUES(17,'yueyawang');
INSERT INTO music VALUES(18,'kong');
INSERT INTO music VALUES(19,'MOM');
INSERT INTO music VALUES(20,'Sold Out');

output:

music_name
kong
MOM
select distinct music_name
from follow f
right join music_likes ml
on f.follower_id=ml.user_id
right join music m
on ml.music_id=m.id
where f.user_id=1  
AND music_name not in(
    select music_name
    from music_likes mls
    right join music m1
    on mls.music_id=m.id
    where mls.user_id=1
)
order by music_name;

Level 3 queries to the user_id user in the follow table, and recommends the favorite music of the people he follows

Task description
Assume that there are several simplified data tables in the music database:
the following followtable, the first column is the person who follows id, and the second column is the person who is followed id. These two columns idform the primary key

+---------+-------------+
| user_id | follower_id |
+---------+-------------+
|       1 |           2 |
|       1 |           4 |
|       2 |           3 |
+---------+-------------+

The first row of this table represents the users idwho 1follow the user for the second row of the table represents the users who follow the user for the third row idof the table represents the users who follow the user for the user2
id1id4
id2id3

Personal favorite music music_likestable, the first column is the user id, the second column is the favorite music id, the composition of this 2column idis the primary key

+---------+----------+
| user_id | music_id |
+---------+----------+
|       1 |       17 |
|       2 |       18 |
|       2 |       19 |
|       3 |       20 |
|       4 |       17 |
+---------+----------+

The first row of this table represents the music that iduser 1likes music_idfor ... The fifth row of this table represents the music that user i likes for Music table, the first column is music i , the second column is music , is primary key17
d4music_id17
musicdnameid

+----+------------+
| id | music_name |
+----+------------+
| 17 | yueyawang  |
| 18 | kong       |
| 19 | MOM        |
| 20 | Sold Out   |
+----+------------+

Please write a MYSQLquery to recommend the favorite music to the users followin the table . user_idDon't recommend music that the user already likes, and sort it first in ascending order of and then in followascending order of . The results you return should not contain duplicates The above query results are as follows:user_idmusicmusic_name

+------------+
| music_name |
+------------+
| kong       |
| MOM        |
+------------+

Example 1
input:

CREATE TABLE follow (
user_id int(4) NOT NULL,
follower_id int(4) NOT NULL,
PRIMARY KEY (user_id,follower_id));

CREATE TABLE music_likes (
user_id int(4) NOT NULL,
music_id int(4) NOT NULL,
PRIMARY KEY (user_id,music_id));

CREATE TABLE music (
id int(4) NOT NULL,
music_name varchar(32) NOT NULL,
PRIMARY KEY (id));

INSERT INTO follow VALUES(1,2);
INSERT INTO follow VALUES(1,4);
INSERT INTO follow VALUES(2,3);

INSERT INTO music_likes VALUES(1,17);
INSERT INTO music_likes VALUES(2,18);
INSERT INTO music_likes VALUES(2,19);
INSERT INTO music_likes VALUES(3,20);
INSERT INTO music_likes VALUES(4,17);

INSERT INTO music VALUES(17,'yueyawang');
INSERT INTO music VALUES(18,'kong');
INSERT INTO music VALUES(19,'MOM');
INSERT INTO music VALUES(20,'Sold Out');

output:

user_id    music_name
1    kong
1    MOM
2    Sold Out
SELECT DISTINCT follow.user_id,music_name
FROM follow ,music_likes,music  
WHERE follow.follower_id=music_likes.user_id 
AND music.id=music_likes.music_id
AND music_id NOT IN(
    SELECT music_id
    FROM music_likes m
    WHERE m.user_id=follow.user_id
)
ORDER BY user_id,music_name;

Level 4 Query the user's DAU and payment amount

Task description
There are currently 3 business tables, see the following for details:
insert image description here
The required output results are as follows, and the date that has not been paid does not need to be displayed. Please write the corresponding MYSQL
insert image description here
example 1
input:

CREATE TABLE new_user(
  user_id int(11) NOT NULL,
  is_new int(11) NOT NULL,
  PRIMARY KEY (user_id)
);
CREATE TABLE user_pay(
  user_id int(11) NOT NULL,
  pay_money int(11) NOT NULL,
  dt char(20) NOT NULL
);
CREATE TABLE login_record(
  user_id int(11) NOT NULL,
  login_time char(20) NOT NULL,
  dt char(20) NOT NULL
);
insert into new_user values(1,0);
insert into new_user values(2,1);
insert into new_user values(3,1);
insert into new_user values(4,0);
insert into new_user values(5,0);
insert into new_user values(6,1);
insert into new_user values(7,0);
insert into new_user values(8,1);
insert into user_pay values(1,30,'2021-11-10');
insert into user_pay values(1,100,'2021-11-10');
insert into user_pay values(2,500,'2021-11-11');
insert into user_pay values(2,200,'2021-11-12');
insert into user_pay values(3,1000,'2021-11-10');
insert into user_pay values(4,800,'2021-11-12');
insert into user_pay values(6,1200,'2021-11-10');
insert into user_pay values(6,700,'2021-11-14');
insert into login_record values(1,'8:00','2021-11-10');
insert into login_record values(1,'12:00','2021-11-10');
insert into login_record values(1,'13:00','2021-11-10');
insert into login_record values(2,'16:00','2021-11-10');
insert into login_record values(2,'12:35','2021-11-11');
insert into login_record values(2,'18:34','2021-11-12');
insert into login_record values(3,'20:00','2021-11-10');
insert into login_record values(4,'21:00','2021-11-12');
insert into login_record values(5,'21:00','2021-11-13');
insert into login_record values(6,'22:30','2021-11-10');
insert into login_record values(6,'13:30','2021-11-14');

output:

dt    dau    dau_new    total_pay    total_pay_new
2021-11-10    4    3    2330    2200
2021-11-11    1    1    500    500
2021-11-12    2    1    1000    200
2021-11-14    1    1    700    700
SELECT ftemp1.dt AS dt,dau,dau_new,total_pay,total_pay_new
FROM(SELECT temp1.dt,dau,dau_new
     FROM(SELECT tempt2.dt,COUNT(is_new) AS dau_new
          FROM (SELECT DISTINCT user_id,dt FROM login_record)
          AS tempt2,new_user
          WHERE new_user.user_id=tempt2.user_id
          GROUP BY tempt2.dt,is_new
          HAVING is_new=1) AS temp1,(SELECT tempt2.dt,COUNT(is_new) AS dau
                                     FROM (SELECT DISTINCT user_id,dt FROM login_record) AS tempt2,new_user
                                     WHERE new_user.user_id=tempt2.user_id
                                     GROUP BY tempt2.dt)AS temp2
     WHERE temp1.dt=temp2.dt) AS ftemp1,(SELECT temp3.dt,total_pay,total_pay_new
                                         FROM (SELECT dt,SUM(pay_money) AS total_pay
                                               FROM user_pay

                                               GROUP BY dt)AS temp3,(SELECT user_pay.dt,SUM(pay_money) AS total_pay_new
                                                                     FROM user_pay,new_user
                                                                     WHERE user_pay.user_id=new_user.user_id
                                                                     GROUP BY dt,is_new
                                                                     HAVING is_new=1) AS temp4
                                         WHERE temp3.dt=temp4.dt) AS ftemp2 WHERE ftemp1.dt=ftemp2.dt

Level 5 Query the next-day retention rate of new users of a website on each date

Task description
Task for this level: Query the next-day retention rate of new users of a website on each date.

Related Knowledge
A lot of people log in to a website every day. Please count the next-day retention rate of new users on each date of the website.
There is a login ( login) record table, the profile is as follows:

insert image description here

The user 1represented user_idby row 1 has logged in to the website using the device where the client is. Since it is the first time to log in, it is a new user. The user represented by row 1 has logged in to the website using the client device as . Since it is the first time to log in, he is an old user. The last line indicates that the user logged in to the website using the device of the client is an old user because it is the first time to log in. Please write a statement to query the next-day retention rate of new users on each date. The result retains the number of digits after the decimal point ( rounded after the digit), and the query results are sorted in ascending order of date. The query results of the above example are as follows:22020-10-12id11
4user_id22020-10-13id22
1user_id42020-10-15id12
sql33

insert image description here

The query results show that: there are ( for , , ) new users
2020-10-12logged in , and only ( for , ) are logged in, so the retention rate of new users the next day is ;3user_id2312020-10-132id212020-10-122/3=0.667

2020-10-13No new user is logged in, output0.000;

2020-10-14Logged in 1( user_idfor 4) new users, 2020-10-15, user_idfor 4users logged in, so 2020-10-14the retention rate of new users the next day 1/1=1.000;

2020-10-15No new user logged in, output 0.000;

Note:
1. The new user in this question is not a real new user definition, but a new user definition given in this question;
2. The function MYSQLto calculate the difference between dates t2and dates is: ; 3. The function to round a reserved bit for a field is: ; 4. The function to set the empty value of a certain field is: .t1datediff(t2,t1)
MYSQLtotal3round(total,3)
MYSQLtotal0ifnull(total,0)

Example 1
input:

drop table if exists login;
CREATE TABLE login (
id int(4) NOT NULL,
user_id int(4) NOT NULL,
client_id int(4) NOT NULL,
date date NOT NULL,
PRIMARY KEY (id));

INSERT INTO login VALUES
(1,2,1,'2020-10-12'),
(2,3,2,'2020-10-12'),
(3,1,2,'2020-10-12'),
(4,2,2,'2020-10-13'),
(5,1,2,'2020-10-13'),
(6,3,1,'2020-10-14'),
(7,4,1,'2020-10-14'),
(8,4,1,'2020-10-15');

output:

date    p
2020-10-12    0.667
2020-10-13    0.000
2020-10-14    1.000
2020-10-15    0.000
SELECT first1.date,ROUND (COUNT(second2.user_id)/COUNT(first1.user_id),3)AS p
FROM(
    SELECT user_id, MIN(date) AS date
    FROM login
    GROUP BY user_id)first1
LEFT JOIN login second2 ON first1.user_id=second2.user_id
AND second2.date=date_add(first1.date,INTERVAL+1 DAY)
GROUP BY first1.date
UNION
SELECT date,0 AS p
FROM login
WHERE date NOT IN(
    SELECT MIN(date)
    FROM login
    GROUP BY user_id)
ORDER BY date;

Level 6 Query users who meet the conditions

Task Description
Some students will purchase online training courses to learn. An educational website will generate an order for the purchase record and save it to the database. There is an order information table ( order_info), the content of which is as follows:

insert image description here

The first 1row indicates user_idthat 557336the user 2021-10-10who is using client_idthe client of 1 places C++an order for a course, but the status is that the purchase is not successful. The first 2row is successfully purchased.

Query the users who meet the following conditions:
in 2021-10-15the future, if there is a 2single and more than one course or courses or courses 2with a status of successful purchase , then output the user's and the date of the first successful purchase that meets the condition , And the date of the second successful purchase that meets the previous conditions , as well as the number of successful purchases , and the output results are sorted in ascending order.C++JavaPythonuser_idfirst_buy_datesecond_buy_datecntuser_id

Function prompt
1. row_number() over(partition by某字段 order by 某字段): The window function is grouped by a certain field, and 1the sequence number from the beginning is generated.
2. count(*) over(partition by 某字段): Find the total after grouping.

Example 1
input:

drop table if exists order_info;
CREATE TABLE order_info(
id int(4) NOT NULL,
user_id int(4) NOT NULL,
product_name char(20) NOT NULL,
status char(20) NOT NULL,
client_id int(4) NOT NULL,
date date NOT NULL,
PRIMARY KEY (id));

INSERT INTO order_info VALUES
(1,557336,'C++','no_completed',1,'2021-10-10'),
(2,230173543,'Python','completed',2,'2021-10-12'),
(3,230173543,'Python','completed',2,'2021-10-15'),
(4,557336,'Java','completed',1,'2021-10-15'),
(5,230173543,'Java','no_completed',2,'2021-10-16'),
(6,230173543,'Java','completed',2,'2021-10-20'),
(7,230173543,'C++','completed',2,'2021-10-21'),
(8,557336,'Java','completed',1,'2021-10-21'),
(9,557336,'离散数学','completed',1,'2021-10-22'),
(10,230173543,'离散数学','completed',2,'2021-10-22'),
(11,663466,'离散数学','completed',3,'2021-10-22'),
(12,663466,'C++','completed',3,'2021-10-22'),
(13,663466,'Python','no_completed',3,'2021-10-23'),
(14,663466,'Python','completed',3,'2021-10-24'),
(15,663466,'C++','completed',3,'2021-10-25'),
(16,8912311,'Java','completed',1,'2021-10-25'),
(17,3345600,'高等数学','completed',1,'2021-10-27'),
(18,3345600,'数学分析','completed',1,'2021-10-28'),
(19,3345600,'数据库系统','completed',1,'2021-10-28');

output:

user_id    first_buy_date    second_buy_date    cnt
663466    2021-10-22    2021-10-24    3
230173543    2021-10-20    2021-10-21    2
SELECT user_id,
MIN(CASE WHEN num=1 THEN date END) AS first_buy_date,
MAX(CASE WHEN num=2 THEN date END) AS second_buy_date,
COUNT(1) AS cnt
FROM(
    SELECT*,row_number()over(PARTITION BY user_id ORDER BY date) AS num 
    FROM order_info
    WHERE status='completed'
    AND date >'2021-10-15'
    AND product_name IN('C++','Java','Python'))TABLE2
GROUP BY user_id
HAVING COUNT(1)>=2;

Level 7 queries the largest total supply of each project number by part number and the part number, and first sorts in ascending order of project number, and then sorts in ascending order of part number.

Task description
Query the largest total supply of each project number by part number and the part number, and sort by the ascending order of the project number first, and then by the ascending order of the part number.

Relevant knowledge
The supply situation table is composed SPJof supplier code ( SNO), part code ( PNO), project code ( JNO), and supply quantity ( QTY), which identifies the quantity that a certain supplier
supplies a certain part to a certain project QTY.
SPJThe table is as follows:

insert image description here

The table has been built SPJ, and the structure information is as follows:

insert image description here

CREATE VIEW nextdata(JNO,PNO,maxsum)
AS
SELECT JNO,PNO,SUM(QTY)
FROM SPJ
GROUP BY JNO,PNO
ORDER BY JNO,PNO;
SELECT JNO,PNO,maxsum
FROM nextdata AS S1
WHERE S1.maxsum >= ALL(
    SELECT maxsum
    FROM nextdata AS S2
    WHERE S1.JNO = S2.JNO);

Guess you like

Origin blog.csdn.net/weixin_51571728/article/details/127902356