mysql 练习题 杂集

01练习根据图片内容解答问题

截屏2020-12-18 下午2.44.59.png
1生成满足上述表的信息
# 表A
create table A(Member varchar(10),Log_time datetime ,URL varchar(100));

# 表B
create table B(URL varchar(100) ,Log_class varchar(55)); 

2.  #时间最早 这个用户记录指数是指 理财相关的用户记录
---> 解析 下面sql语句中 两个括号内都使用了半连接
select A.URL,
(select count(1) from A where Member_ID = a.out.Member_ID AND Log_class = '理财')
from A a_out  join B on a_out.URL = B.URL 
where Log_class = '理财'  AND Log_time =
(select MIN(Log_time) from A  where Member_ID = a_out.Member_ID AND Log_class = '理财')

3. update A set MeMber_ID = '0002567543' where  MeMber_ID in (select MeMber_ID Form A join B on A.URL = B.URL AND B.Log_class = '购物' AND A.Log_time  betwwen '2018-05-01 00:00:00 and 2018-05-01 00:23:59  )

3. 标准的update join写法
update A join  B  on  A.URL = B.URL set  Member_ID ='0002567543' where Log_time betwwen '2018-05-01 00:00:00 and 2018-05-01 00:23:59  AND B.Log_class = '购物'
 

02 根据下表完成问题

成绩表(score):

年级(grade) 姓名(name) 数学(math) 语文(language)
高一 A 100 97
高二 A 123 98
高三 A 135 100
高一 B 89 129
高二 B 140 130
高三 B 140 133
高一 C 105 97
高二 C 108 107
高三 C 125 100

作弊表(cheat):

年级(grade) 姓名(name) 数学(math) 语文(language)
高一 A 100 97
高二 B 140 130
高三 C 125 100

-->用一条sql语句查询每个人每科的平均成绩

select name, AVG(math) as '数学平均成绩' , AVG(language) '语文平均成绩' FROM score group by name;
--->展示结果:

mysql> select name, AVG(math) as '数学平均成绩' , AVG(language) '语文平均成绩' FROM score group by name;
+------+--------------------+--------------------+
| name | 数学平均成绩       | 语文平均成绩       |
+------+--------------------+--------------------+
| A    |           119.3333 |            98.3333 |
| B    |           123.0000 |           130.6667 |
| C    |           112.6667 |           101.3333 |
+------+--------------------+--------------------+
3 rows in set (0.00 sec)

--->用一条sql语句把成绩表单换成如下形式

姓名 高一语文 高二语文 高三语文 高一数学 高二数学 高三数学
A
B
C
select name ,
min(case when grade = '高一' 
          then  language
          else NULL end) as '高一语文',
min(case when grade = '高二' 
          then  language
          else NULL end) as '高二语文',
min(case when grade = '高三' 
          then  language
          else NULL end) as '高三语文',
min(case when grade = '高一' 
          then  math
          else NULL end) as '高一数学',
min(case when grade = '高二' 
          then  math
          else NULL end) as '高二数学',
min(case when grade = '高三' 
          then  math
          else NULL end) as '高三数学'
FROM score group by name;

-->最终结果显示:

mysql> mysql> select name , min(case when grade = '高一'            then  language           else NULL end) as '', min(case when grade = '高二'            then  language           else NULL end) as '高二语文', min(case when grade = '高三'            then  language           else NULL end) as '高三语文', min(case when grade = '高一'            then  math  else NULL end) as '高一数学', min(case when grade = '高二' then  math else NULL end) as '  二 数学', min(case when grade = '高三' then math else NULL end) as '      学' FROM score group by name; 
+------+--------------+--------------+--------------+--------------+--------------+--------------+
| name | 高一语文     | 高二语文     | 高三语文     | 高一数学     | 高二数学     | 高三数学     |
+------+--------------+--------------+--------------+--------------+--------------+--------------+
| A    |           97 |           98 |          100 |          100 |          123 |          135 |
| B    |          129 |          130 |          133 |           89 |          140 |          140 |
| C    |           97 |          107 |          100 |          105 |          108 |          125 |
+------+--------------+--------------+--------------+--------------+--------------+--------------+
3 rows in set (0.00 sec)

--> 班级内发现作弊情况 用sql语句剔除作弊成绩后 对总成绩排序(使用排序函数)

--> 解析如何去除两张表内相同的数据
注意: (grade,name) not in  做判断的时候 后面的字段要和前面的相同
select name ,SUM(math) + SUM(language) total_score
from score 
where (grade,name) not in 
(select s.grade as grade ,s.name as name from score s join cheat on s.grade = cheat.grade AND s.name = cheat.name)
group by name
order by total_score;

--->第一部 去重后的成绩显示
mysql> select *from score where (grade,name) not in (select s.grade as grade ,s.name as name from score s join cheat on s.grade = cheat.grade AND s.name = cheat.name);
+--------+------+------+----------+
| grade  | name | math | language |
+--------+------+------+----------+
| 高二   | A    |  123 |       98 |
| 高三   | A    |  135 |      100 |
| 高一   | B    |   89 |      129 |
| 高三   | B    |  140 |      133 |
| 高一   | C    |  105 |       97 |
| 高二   | C    |  108 |      107 |
+--------+------+------+----------+

--->最终结果显示:

mysql> select name ,SUM(math) + SUM(language) total_score
    -> from score 
    -> where (grade,name) not in 
    -> (select s.grade as grade ,s.name as name from score s join cheat on s.grade = cheat.grade AND s.name = cheat.name)
    -> group by name
    -> order by total_score;
+------+-------------+
| name | total_score |
+------+-------------+
| C    |         417 |
| A    |         456 |
| B    |         491 |
+------+-------------+
3 rows in set (0.00 sec)


3.根据图片完成下面问题

截屏2020-12-23 下午1.38.57.png
----> sql中 时间格式的转换:
mysql> select year('2020-10-10');
+--------------------+
| year('2020-10-10') |
+--------------------+
|               2020 |
+--------------------+
mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2020-12-23 13:47:41 |
+---------------------+
1 row in set (0.00 sec)

mysql> select date_format(now(),'%Y-%h-%d');
+-------------------------------+
| date_format(now(),'%Y-%h-%d') |
+-------------------------------+
| 2020-01-23                    |
+-------------------------------+
1 row in set (0.00 sec)

---> 进入正题
select  city_name,
date_format(sale_ord_tm,'%Y-%h-%d') as '日期',
count(1) as '订单总量',
min(price) as '最低价格'
From A join B on A.city_id = B.city.id 
group by date_format(sale_ord_tm,'%Y-%h-%d'), A.city_id;


4.根据下图做题:

截屏2020-12-23 下午1.57.30.png

--->计算每个人的消费金额,消费频次,购买产品数量.第一次购买时间和最后一次购买时间

--->解析 既然是每个人 就需要使用 gourp by
select  CustomerID,
SUM(Slaes) as '消费金额',
count(1) as'消费频次',
SUM(Quantity) as '购买产品数量',
min(OrderDate) as '第一次购买时间',
max(OrderDate) as '最后一次的购买时间'
from OrderInfo
 group by CustomerID;

--->请结合订单表 计算出每一个SKU被多少客户购买了

--->解析每一个SKU 也要使用group by 分组
select SKU, count(distinct OI.CustomerID)
FORM  OrderInfo OI  join  OrderDetail OD 
on  OI.OrderID = OD.orderID     
group by SKU;

--->请结合OrderInfo表和OrderDetail表,找出购买了SKU1又购买了SKU2产品的人

---> 解析 先找到购买SKU1的人 在找到购买 SKU2的人 
条件就是 这个人同时买了SKU1 和 SKU2
select distinct OI.CustomerID
FROM (OrderInfo OI join OrderDetail OD on OI.OrderID = OD.orderID )  #买SKU1的人
join (OrderInfo OI2 join OrderDetail OD2 on OI2.OrderID = OD2.orderID ) # 买SKU2的人
on OI.CustomerID = OI2.CustomerID # 买sku1和sku2的那个人
where OD.SKU = 'SKU1' AND OD2.SKU = 'SKU2';

--->请结合OrderInfo表和OrderDetail表,计算出2016年的客户在2017年的回柜率(Retention Rate)

--->解析 就是计算出 2016和2017年都购买产品的同一批客户数量/2016年购买产品的同一批客户数量
select count(distinct OI.CustomerID) / select count(distinct CustomerID) from OrderInfo where
OrderID = OI.order AND year(OrderDate) = 2016 as 'Retention Rate'
FROM orderInfo OI  join OrderDetail OD 
on OI.orderID = OD.orderID 
where  year(OI.OrderDate) = 2016 AND year(OI.OrderDate) = 2017 ;  

---> 另一种解法
SELECT COUNT(DISTINCT CustomerID) / (SELECT COUNT(DISTINCT CustomerID) FROM OrderInfo WHERE year(OrderDate) = 2016) AS 'Retention Rate'
FROM OrderInfo WHERE CustomerID IN (SELECT CustomerID FROM OrderInfo WHERE year(OrderDate) = 2016 ) AND year(OrderDate) = 2017

--->请结合OrderInfo表和OrderDetail表,计算出2017年新老客户的二购率(Repeat Purchase Rate)

--->解析二购率 就是2017年 CustomerID的数量大于2的/2017年的总客户购买数量
select count(OrderID) as n / select count(DISTINCT CustomerID) from OrderInfo where year(OrderDate) = 2017  as 'Repeat Purchase Rate'
FROM  OrderInfo OI join OrderDetail OD 
on OI.OrderID = OD.OrderID AND year(OI.OrderDate) = 2017
group by OrderID having n >= 2;

---> 另一种解法 :
SELECT COUNT(1) / (SELECT COUNT(DISTINCT CustomerID) FROM OrderInfo WHERE year(OrderDate) = 2017) AS 'Repeat Purchase Rate'
FROM 
(SELECT CustomerID
FROM OrderInfo 
WHERE year(OrderDate) = 2017
GROUP BY CustomerID
HAVING COUNT(1) >= 2) Repeat ;

--->请通过订单表OrderInfo把客户按2017年消费金额,从高到底100等分,计算出每等分中的总客户数量,总订单量,总消费金额,总购买产品数量


你可能感兴趣的:(mysql 练习题 杂集)