SQL在数据分析中的应用案例(一)

MySQL应用:

数据查询与过滤,数据聚合,数据表间的连接,数据的增、改、删,SQL进阶用法

温馨提示:

 


案例:【电商数据库表结构及字段定义】

1、 数据查询与过滤

CONCAT

从顾客信息(customer_info)表中选取顾客号码(customer_id),姓名(last_name,first_name)和电话(phone_number)(注意选取列的顺序)

提示:使用CONCAT函数合并`last_name`(姓),`first_name`(名)字段, 为新产生的字段命名为`name`(姓名)

SELECT
	customer_id,
	CONCAT(last_name, first_name) AS 'name',
	phone_number
FROM
	customer_info;

 WHERE+AND或BETWEEN AND 

选取价格在2030之间(包含2030)的产品,列出产品号码(product_id),产品名称(product_name),产品单价(price)(注意选取列的顺序)

SELECT
	product_id,
	product_name,
	price
FROM
	product_info
WHERE
	price >= '20'
AND price <= '30';

等价于:

SELECT
	product_id,
	product_name,
	price
FROM
	product_info
WHERE
	price BETWEEN 20
AND 30;

IN

选取来自河北省及山西省所有顾客的顾客号码(customer_id)、姓名(last_name first_name)、省份(province)(注意选取列的顺序);

提示:你可以使用CONCAT函数合并`last_name`,`first_name`字段,为新生成的字段命名为`name`

SELECT
	customer_id,
	CONCAT(last_name, first_name) AS 'name',
	province
FROM
	customer_info
WHERE
	province IN ('河北省', '山西省');

或

SELECT
	customer_id,
	CONCAT(last_name, first_name) AS 'name',
	province
FROM
	customer_info
WHERE
	province = '河北省'
OR province = '山西省';

!=

 选取所有不在珠海市和绍兴市的供应商,列出所有供应商信息(注意选取列的顺序)

SELECT
	*
FROM
	supplier_info
WHERE
	city != '珠海市'
AND city != '绍兴市';

或

SELECT
	*
FROM
	supplier_info
WHERE
	city NOT IN ('珠海市', '绍兴市');

ORDER BY/LIMIT

选取价格最高的前5件产品, 列出产品号码(product_id),产品名称(product_name)以及产品单价(price)(注意选取列的顺序)

SELECT
	product_id,
	product_name,
	price
FROM
	product_info
ORDER BY
	price DESC
LIMIT 5;

选取价格在第三到第八之间(包含第三和第八)的产品

SELECT
	product_id,
	product_name,
	price
FROM
	product_info
ORDER BY
	price DESC
LIMIT 2,6;

DISTINCT

从顾客信息表(customer_info)中选取不重复的城市(city)以及省份(province)作为顾客来源地区。

SELECT DISTINCT
	city,
	province
FROM
	customer_info;

2、数据聚合

SUM

使用订单信息列表(order_info)中数据,计算2017年总营业额(total_revenue),添加备注信息字段,填入‘2017总营收字符串作为备注信息(other_info)

SELECT
	'2017总营收' AS other_info,
	SUM(payment_amount) AS total_revenue
FROM
	order_info
WHERE
	DATE_FORMAT(create_time, '%Y') = '2017';

或

SELECT
	'2017总营收' AS other_info,
	SUM(payment_amount) AS total_revenue
FROM
	order_info
WHERE
	create_time BETWEEN '2017-01-01'
AND '2017-12-31';

COUNT

2017年间,计算总共完成了多少个订单,创建`订单数目(order_count)`字段,计算总共有多少位顾客完成过订单,创建`顾客数目(customer_count)`字段

提示:同一位顾客一年内可以消费多次;(注意选取列的顺序)

SELECT
	COUNT(*) AS 'order_count',
	COUNT(DISTINCT customer_id) AS 'customer_count'
FROM
	order_info
WHERE
	DATE_FORMAT(create_time, '%Y') = '2017';

或

WHERE create_time BETWEEN '2017-01-01' AND '2017-12-31';

MAX、MIN、AVG

使用产品信息表数据,计算所有产品的最高售价(max_price),最低售价(min_price)以及平均售价(average_price)。(注意选取列的顺序)

SELECT
	MAX(price) AS 'max_price',
	MIN(price) AS 'min_price',
	AVG(price) AS 'average_price'
FROM
	product_info;

HAVING

使用产品信息表数据,为每位供应商计算其销售产品的最高售价(max_price),最低售价(min_price)以及平均售价(average_price)

选择最高售价大于2倍平均售价的结果,列出供应商号码,最高售价,最低售价,平均售价(注意选取列的顺序)

SELECT
	supplier_id,
	MAX(price) AS 'max_price',
	MIN(price) AS 'min_price',
	AVG(price) AS 'average_price'
FROM
	product_info
GROUP BY
	supplier_id
HAVING
	max_price > 2 * average_price;

 

使用订单明细数据表( order_details)计算每样产品的总销售次数 (total_times) 以及总销售数量 (total_count) ,并选取总销售数量排名前9名的产品号码, 总销售数量,总销售次数 (注意选取列的顺序)

提示: 一样产品在一个订单中出现过算一次销售(比如A产品在订单1中出现过2次,该产品的销售次数应计为1次)

SELECT
	product_id,
	SUM(sales_count) AS 'total_count',
	COUNT(DISTINCT order_id) AS 'total_times'
FROM
	order_details
GROUP BY
	product_id
ORDER BY
	total_count DESC
LIMIT 9;

3、数据表间的连接

INNER JOIN

查询所有供应商公司的在售产品信息

列出所有供应商公司的产品信息,公司名称,以及所在的省份

SELECT
	p.*,
	s.company,
	s.province
FROM
	product_info p
INNER JOIN supplier_info s ON p.supplier_id=s.supplier_id;

查询所有在2018年1月1日之后消费过的顾客信息

列出顾客号码(customer_id),顾客姓名(last_name,first_name),城市(city)以及电话号码(phone_number) (注意选取列的顺序)

注:每位顾客仅在结果中显示一次

SELECT DISTINCT
	c.customer_id,
	CONCAT(c.last_name, c.first_name) AS 'name',
	c.city,
	c.phone_number
FROM
	customer_info c
INNER JOIN order_info o ON c.customer_id = o.customer_id
WHERE
	o.create_time > '2018-01-01';

 

 

LEFT JOIN

查询所有的产品信息以及供应商公司信息

结果包含所有产品信息行以及对应供应商信息,没有对应信息的产品以空值(NULL)表示供应商信息

SELECT
	*
FROM
	product_info p
LEFT JOIN supplier_info s ON p.supplier_id = s.supplier_id;

查询所有供应商以及其提供的产品信息

列出供应商号码(supplier_id),公司(`company),产品号码(product_id, 产品名称(product_name

注: 结果必须包含所有供应商信息,即使供应商没有提供产品(注意选取列的顺序)

SELECT
	s.supplier_id,
	s.company,
	p.product_id,
	p.product_name
FROM
	supplier_info s
LEFT JOIN product_info p ON s.supplier_id = p.supplier_id;

查询所有顾客信息以及其最近购买日期

列出顾客号码(customer_id),姓名(name),以及最近购买日期(last_create_time)(注意选取列的顺序)

注:结果必须包含所有顾客信息,即使顾客没有完成过订单

关键语句:SELECT、CONCAT、LEFT JOIN、GROUP BY、MAX

SELECT
	c.customer_id,
	CONCAT(c.last_name, c.first_name) AS 'name',
	MAX(o.create_time) AS 'last_create_time'
FROM
	customer_info c
LEFT JOIN order_info o ON c.customer_id = o.customer_id
GROUP BY
	c.customer_id;

查询所有201811日之后各个订单中购买数量超过10的订单以及产品的详细信息

列出订单号码(order_id),订单日期(create_time, 购买数量(sales_count),产品号码(product_id),产品名称(product_name)(注意选取列的顺序)

提示:你需要使用`订单信息`order_info)、`订单明细`order_details)、`产品信息`product_info)表。

关键语句:SELECT、LEFT JOIN(三个表连接)、WHERE+AND

SELECT
	od.order_id,
	oi.create_time,
	od.sales_count,
	p.product_id,
	p.product_name
FROM
	order_details od
LEFT JOIN order_info oi ON od.order_id = oi.order_id
LEFT JOIN product_info p ON od.product_id = p.product_id
WHERE
	oi.create_time > '2018-01-01'
AND od.sales_count > 10;


 

RIGHT JOIN 

4、数据的增、改、删

  • 获取数据表信息:DESCRIBE
  • 数据的插入:INSERT INTO
  • 数据的修改:UPDATE SET
  • 数据的删除:DELETE FROM

DESCRIBE

关联字列出数据表的详细信息:1、数据表的字段(列);2、各个字段的数据类型。

列出顾客信息表的详细信息:

DESCRIBE customer_info;

INSERT INTO

新纪录的字段与表中原纪录的个数、数据类型都要相同

添加新的产品信息

`product_id`(产品号码  : 81

`product_name`(产品名称):洗洁精

`supplier_id`(供应商号码) : 20

`price`(产品单价):9.99

`description`(产品描述): 350ml

INSERT INTO product_info
VALUES
	(
		81,
		'洗洁精',
		20,
		9.99,
		'350ml'
	);

UPDATE SET

使用WHERE语句实现,确认将要修改的记录是有效记录;

新值的数据类型必须与表中定义好的数据类型保持一致。

请修改#6号产品(product_id)红枣的价格(price)为当前价格减去5元。

UPDATE product_info
SET price = 20
WHERE
	product_id = 6;

DELETE FROM

使用WHERE语句实现,确认将要删除的记录是目标记录;

5、SQL进阶

子查询

(1)单行单列过滤条件子查询

列出所有产品单价高于或等于最高产品单价50%产品的详细信息

SELECT
	*
FROM
	product_info
WHERE
	price >= 0.5 * (
		SELECT
			MAX(price)
		FROM
			product_info
	);

选取所有在平均价格以上的产品信息

列出产品号码(product_id, 产品名称(product_name, 产品单价(price)。(注意选取列的顺序)

SELECT
	product_id,
	product_name,
	price
FROM
	product_info
WHERE
	price > (
		SELECT
			AVG(price) AS 'product_avg_price'
		FROM
			product_info
	);

并在以上基础上,增加 “product_avg_price” (产品平均售价)常量列,在每一行中显示产品的平均售价(product_avg_price)。

SELECT
	product_id,
	product_name,
	price,
	(
		SELECT
			AVG(price)
		FROM
			product_info
	) AS 'product_avg_price'
FROM
	product_info
HAVING
	price > product_avg_price;

 

(2)多行单列过滤条件子查询

列出所有广东省供应商供应的产品详细信息

SELECT
	*
FROM
	product_info
WHERE
	supplier_id IN (
		SELECT
			supplier_id
		FROM
			supplier_info
		WHERE
			province = '广东省'
	);

在不使用表连接(JOIN)的前提下,选取所有供应商来自于珠海市的产品信息

列出产品号码(product_id, 产品名称(product_name,供应商号码(supplier_id), 产品单价(price)(注意选取列的顺序)

SELECT
	product_id,
	product_name,
	supplier_id,
	price
FROM
	product_info
WHERE
	supplier_id IN (
		SELECT
			supplier_id
		FROM
			supplier_info
		WHERE
			city = '珠海市'
	);

在不使用表连接(JOIN)的前提下,计算201811日以来出售的每样产品的销售总数量(total_sales),选取销量最高的前8样产品

列出产品号码(product_id),销售总数(total_sales),将结果以销售总数从大到小排列

SELECT
	product_id,
	SUM(sales_count) AS 'total_sales'
FROM
	order_details
WHERE
	order_id IN (
		SELECT
			order_id
		FROM
			order_info
		WHERE
			create_time >= '2018-01-01'
	)
GROUP BY
	product_id
ORDER BY
	total_sales DESC
LIMIT 8;

(3)临表子查询

列出产品数目最多的供应商号码

SELECT
	supplier_id
FROM
	(
		SELECT
			COUNT(*) AS 'product_count',
			supplier_id
		FROM
			product_info
		GROUP BY
			supplier_id
		ORDER BY
			product_count DESC
		LIMIT 1
	) AS s;

 

为每样产品计算总销售额,列出产品号码(product_id),产品名称(product_name),总销售额(total_sales)(注意选取列的顺序)

注:返回答案包含没有出售过的产品

提示: 使用订单明细表计算产品的总销售额

SELECT
	p.product_id,
	p.product_name,
	od.total_sales
FROM
	product_info p
LEFT JOIN (
	SELECT
		product_id,
		SUM(sales_count * sales_price) AS 'total_sales'
	FROM
		order_details
	GROUP BY
		product_id
) AS od ON p.product_id = od.product_id;

选取近3天(2018.05.04-2018.05.06)销售额(`sales_rev`)最高的产品类别TOP3,按照产品号码(`product_id`)、销售额(`sales_rev`)顺序输出。

提示:

使用订单信息表(`order_info`)获取时间相关信息

使用订单明细表(`order_details`)获取产品相关信息

关键语句:JOIN、ORDER BY、LIMIT、临表子查询

SELECT
	od.product_id,
	od.sales_count * od.sales_price AS 'sales_rev'
FROM
	order_details od
INNER JOIN (
	SELECT
		order_id,
		create_time
	FROM
		order_info
	WHERE
		create_time BETWEEN '2018-05-04'
	AND '2018-05-06'
) AS oi ON od.order_id = oi.order_id
ORDER BY
	sales_rev DESC
LIMIT 3;

条件判断语句

 根据各位顾客的总消费额计算消费级别 

SELECT
	customer_id,
	CASE
		WHEN payment_amounts >= 5000 THEN 'VIP3'
		WHEN payment_amounts >= 2000 AND payment_amounts < 5000 THEN 'VIP2'
		WHEN payment_amounts >= 1000 AND payment_amounts < 2000 THEN 'VIP1'
		ELSE '普通'
	END AS 'customer_level'
FROM
	(
		SELECT
			customer_id,
			SUM(payment_amount) AS 'payment_amounts'
		FROM
			order_info
		GROUP BY
			customer_id
	) AS customer_payments;

 

返回产品信息,增加新数据列 售价级别(price_level

售价级别由平均产品价格计算得出

`产品单价`(`price`) 小于平均售价,级别为1

`产品单价` (`price`) 大于等于平均售价小于2倍平均售价,级别为2

`产品单价` (`price`) 大于等于2倍平均售价,级别为3

列出产品号码(product_id),产品名称(product_name),产品单价(price),售价级别(price_level)(注意选取列的顺序)

关键语句:

CASE   WHEN 判定条件 THEN 判定结果

ELSE 默认值

END AS `售价级别`

SELECT
	p.product_id,
	p.product_name,
	p.price,
	CASE 
		WHEN price < (SELECT AVG(price) FROM product_info) THEN 1
		WHEN price >= 2 * (SELECT AVG(price) FROM product_info) THEN 3
		ELSE 2
	END AS 'price_level'
FROM
	product_info p;

 

计算各年度、各季度的订单数量(`order_quantity`)。按照年度(`years`)、季度(`quarter`)、订单数量(`order_quantity`)顺序列出。提示:

使用Year() 获得时间类型字段的年份;

使用Month() 获得时间类型字段的月份;

季度用1-2-3-4表示(1-3月为1季度,以此类推);

关键语句:CASE WHEN ()THEN ()END、COUNT

SELECT
	COUNT(order_id) AS 'order_quantity',
	YEAR (create_time) AS 'years',
	CASE
		WHEN MONTH (create_time)<4 THEN 1
		WHEN MONTH (create_time)>=4 AND MONTH (create_time)<7 THEN 2
		WHEN MONTH (create_time)>=7 AND MONTH (create_time)<10 THEN 3
		ELSE 4
	END AS 'quarter'
FROM
	order_info
GROUP BY years, quarter;


或
    CASE 
		WHEN MONTH(create_time) > 9 THEN 4
		WHEN MONTH(create_time) > 6 THEN 3
		WHEN MONTH(create_time) > 3 THEN 2
		ELSE 1
	END AS 'quarter'

SQL语句优化

 

  • 16
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 60
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 60
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值