01练习根据图片内容解答问题
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.根据图片完成下面问题
----> 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.根据下图做题:
--->计算每个人的消费金额,消费频次,购买产品数量.第一次购买时间和最后一次购买时间
--->解析 既然是每个人 就需要使用 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等分,计算出每等分中的总客户数量,总订单量,总消费金额,总购买产品数量