mysql_高级语法

本篇是在自学Mysql数据库的过程中,观看一个视频时的个人笔记,感觉这个视频还是不错的,对于已经掌握了基本语法,希望通过实际案例来锻炼的同学有很大的帮助。
在文末会附有视频链接,有兴趣的同学可以看一下。

文章目录

    • 1. 内连接应用
    • 2. 外连接查询
    • 3. 子查询
      • 3.1 不同关键字后面的子查询
      • 3.2 关联子查询和非关联子查询的区分
      • 3.3 分组统计
    • 4.DML
      • 4.1 insert
      • 4.2 update
      • 4.3 delete

1. 内连接应用

  • 列出客户信息和订单日期,并按订单日期排序
SELECT
	u.user_id,
	u.user_name,
	u.eamil,
	oi_order_sn,
	from_unixtime( oi.add_time ) AS ordertime 
FROM
	ecs_order_info AS oi
	INNER JOIN ecs_users AS u ON oi.user_id = u.user_id 
ORDER BY
	ordertime;

数据表的“addtime”字段一般是int型,用于存放时间戳,当想要直观的查看某条记录的addtime,我们需要用from_unixtime()将时间戳转换为日期格式,UNIX_TIMESTAMP()即将日期类型 的转换为时间戳显示。

select UNIX_TIMESTAMP('2018-08-08')------------------->1533657600
select from_unixtime(1533657600)--------------------------->2018-08-08 00:00:00
  • 列出被购买过的商品的名称,类型名称和交易价格(三表内连接)注意表连接时用那个字段
SELECT
	og.goods_id,
	og.goods_name,
	gt.cat_name,
	og.goods_price 
FROM
	 esc_order_goods og INNER JOIN ecs_goods g ON og.goods_id = g.goods_id 
	INNER JOIN ecs_goods_type gt ON g.goods_type = gt.cat_id;

如果是在表连接时,有对表进行where筛选的话,需要先进行限制在连接,可以提高运行效率

  • 显示各订单下每个商品以及该商品的销售额,按照订单号排序

  • 列出被购买过的商品的名称,品牌名称和客户信息(

SELECT
	og.goods_names,
	b.brand_name,
	u.user_name 
FROM
	(
		(
			( ecs_order_goods og INNER JOIN ecs_goods g ON og.goods_id = g.goods_id )
			INNER JOIN ecs_brand b ON g.brand_id = b.brand_id 
		)
		INNER JOIN ecs_order_info oi ON og.order_id = oi.order_id 
	)
	INNER JOIN ecs_users_u ON oi.user_id = USER.id;

可以修改为

SELECT
	og.goods_names,
	b.brand_name,
	u.user_name 
FROM
	ecs_order_goods og
	INNER JOIN ecs_goods g om og.goods_id = g.goods_id
	INNER JOIN ecsecs_brand b ON g.brand_id = b.brand_id
	INNER JOIN ecs_order_info oi ON og.order_id = oi.order_id
	INNER JOIN ecs_users_u ON oi.user_id = USER.id;
  • 找出ecshop用户所有的订单信息
SELECT
	u.user_name,
	oi.order_id,
	og.goods_number,
	og.goods_price 
FROM
	( ecs_order_info oi INNER JOIN ecs_users u ON ou.user_id = u.user_id AND u.user_name = 'ecshop' )
	INNER JOIN ecs_order ON oi.ORDER = og.order_id;

注意表连接时的and,这里是先选取u表里user_name 为ecshop的行,然后和oi表进行内连接。要注意与where的区别

2. 外连接查询

在这里,刚学的时候会发生不知道用左右连接的情况,其实不用区分,两者是可以装换的,
看你想显示那个表的全部数据,左连接 显示左表全部数据,右连接显示右表全部数据;
想要保留左边表的全部数据,用左连接,先要保留右边表的全部数据,用右连接

  • 哪些商品没有被用户购买过

商品表和订单表连接,显示商品表里的全部数据,商品表为主表,没有订单的商品og.goos_id 显示为 NULL,进而可以筛选出

  • 商品类型表中哪些商品类型没有出现在商品表中
SELECT
	* 
FROM
	ecs_goods g
	LEFT JOIN ecs_order_goods og ON g.goods_id = og.goods_id 
WHERE
	og.goods_id IS NULL;

要显示商品类型表里的全部数据,且商品类型表在右边,所以用右连接,没有出现在商品表中的商品类型g.goods_type为NULL

  • 找出没有购买过诺基亚E66上商品的客户信息表
SELECT
	u.* 
FROM
	( ecs_order_info oi INNER JOIN ecs_order_goods og ON oi.order_id = og.order_id )
	RIGHT JOIN ecs_users u ON oi.user_id = u.user_id 
WHERE
	oi.user_id IS NULL;

可修改为

SELECT
	u.* 
FROM
	ecs_order_info oi
	INNER JOIN ecs_order_goods og ON oi.order_id = og.order_id
	RIGHT JOIN ecs_users u ON oi.user_id = u.user_id 
WHERE
	oi.user_id IS NULL;
  • 列出从来没有购买过手机的客户名单
SELECT
	u.* 
FROM
	(
		(
			( ecs_goods g INNER JOIN ecs_goods_type gt ON g.goods_type = gt.cat_id AND gt.cat_name IN ( '手机', '精品手机' ) )
			INNER JOIN ecs_order_goods og ON g.goods_id = og.goods_id 
		)
		INNER JOIN ecs_order_info oi ON og.order_id = oi.ORDER 
	)
	RIGHT JOIN ecs_users u ON oi.USER = u.user_id

可修改为

SELECT
	u.* 
FROM
	ecs_goods g
	INNER JOIN ecs_goods_type gt ON g.goods_type = gt.cat_id 
	AND gt.cat_name IN ( "手机","精品手机" )
	INNER JOIN ecs_order_goods og ON g.goods_id = og.goods_id
	INNER JOIN ecs_order_info oi ON og.order_id = oi.ORDER
	RIGHT JOIN ecs_users u ON oi.USER = u.user_id
  • 所有邮寄方式中那种邮寄方式没有被采用过

  • 列出所有商品和各商品有关的所有订单的日期

SELECT
	g.goods_id,
	g.goods_name,
	oi.order_id,
	from_unixtime( oi.add_time ) ordertime 
FROM
	( ecs_order_info oi INNER JOIN ecs_order_goods og ON oi.order_id = og.ORDER )
	RIGHT JOIN ecs_goods g ON og.goods_id = g.goods_id;

可修改为

SELECT
	g.goods_id,
	g.goods_name,
	oi.order_id,
	from_unixtime( oi.add_time ) ordertime 
FROM
	ecs_order_info oi
	INNER JOIN ecs_order_goods og ON ou.order_id = og.
	ORDER RIGHT JOIN ecs_goods g ON og,
	goods_id = g.goods_id;

3. 子查询

3.1 不同关键字后面的子查询

  • select后面的子查询(列出商品表中各商品的类型名称)
SELECT
	goods_id,
	goods_name,
	( SELECT cat_name FROM ecs_goods_type WHERE cat_id = g.goods_type ) AS  type_name 
FROM
	ecs_goods g;

类型名在 ecs_goods_type中,从里面选出商品对应的类型名称取名为type_nameel
这里还牵涉到mysql执行顺序的问题

  • 模拟orcale中的rownum(行编号)
select
(
select count(*)
from ecs_goods g
where g.goods_id <= eg.goods_id
)
goods_id,goods_name,market_price
from ecs_goods  eg
order by 1;
  • from后面的子查询(哪些用户购买了市场价格大于2000的商品)
SELECT
	u.user_id,
	u.user_name,
	t.market_price 
FROM
	( ecs_users u INNER JOIN ecs_order_into oi ON u.user_id = oi.user_id )
	INNER JOIN ( SELECT * FROM ecs_order_goods og WHERE og.markeyt_rice > 2000 ) AS t ON oi.order_id = t.order_id;

一定不要忘了给虚拟表取别名

  • where后面的子查询(找出市场价格与P806相同的商品信息)
SELECT
	* 
FROM
	ecs_goods 
WHERE
	market_price in ( SELECT markrt_price FROM ecs_goods WHERE goods_name = 'P806' );#P806只有一行信息


SELECT
	* 
FROM
	ecs_goods 
WHERE
	market_price in ( SELECT markrt_price FROM ecs_goods WHERE brand = 1 LIMIT 0, 1 );#当返回的不止一行是,为防止报错,可以用limit来限制来只取一行
SELECT
	* 
FROM
	ecs_goods 
WHERE
	goods_id IN ( SELECT gooes_id FROM ecs_order_goods );#哪些商品被购买过



SELECT
	* 
FROM
	ecs_goods 
WHERE
	goods_id NOT IN ( SELECT gooes_id FROM ecs_order_goods );#哪些商品没被购买过

(in与not in需慎用)
当in或not in 后的表含有空值时,会没有结果,为防止这种情况,可进行限制

SELECT
	* 
FROM
	ecs_brand 
WHERE
	brand_id NOT IN ( SELECT brand_id FROM ecs_goods WHERE brand_is IS NOT NULL );

3.2 关联子查询和非关联子查询的区分

  • 列出购买诺基亚手机的客户信息
SELECT
	* 
FROM
	ecs_users u 
WHERE
	u.user_id IN (
	SELECT
		oi.user_id 
	FROM
		(
			(
				ecs_goods g
				INNER JOIN ecs_goods_type gt ON g.goods_type = gt.cat_id 
				AND gt.cat_name IN ( '手机', '精品手机' ) 
				AND g.goods_name LIKE '诺基亚%' 
			)
			INNER JOIN ecs_order_goods og ON g.goods_id = og.goods_id 
		)
	INNER JOIN ecs_order_info oi ON og.order_id = oi.order_id 
	);
               
  • 找出购买了诺基亚手机但没有购买摩托罗拉手机的客户信息
SELECT
	* 
FROM
	ecs_users u 
WHERE
	u.user_id IN (
	SELECT
		oi.user_id 
	FROM
		(
			(
				ecs_goods g
				INNER JOIN ecs_goods_type gt ON g.goods_type = gt.cat_id 
				AND gt.cat_name IN ( '手机', '精品手机' ) 
				AND g.goods_name LIKE '诺基亚%' 
			)
			INNER JOIN ecs_order_goods og ON g.goods_id = og.goods_id 
		)
		INNER JOIN ecs_order_info oi ON og.order_id = oi.order_id 
	) 
	AND u.uer_id NOT IN (
	SELECT
		oi.user_id 
	FROM
		(
			(
				ecs_goods g
				INNER JOIN ecs_goods_type gt ON g.goods_type = gt.cat_id 
				AND gt.cat_name IN ( '手机', '精品手机' ) 
				AND g.goods_name LIKE '摩托罗拉' 
			)
			INNER JOIN ecs_order_goods og ON g.goods_id = og.goods_id 
		)
	INNER JOIN ecs_order_info oi ON og.order_id = oi.order_id 
	);
  • 哪些商品从未被人购买过

3.3 分组统计

  • 统计每种类型下各商品的销售总额
SELECT
	gt.cat_name,
	IFNULL( sum( og.goods_number * og.goods_prices ), 0 ) amount 
FROM
	( ecs_goods g INNER JOIN ecs_goods_type gt ON g.goods_type = qt.cat_id )
	LEFT JOIN ecs_order_goods og ON g.goods_id = og.goods_id 
GROUP BY
	gt.cat_name
IFNULL(sum(og.goods_number*og.goods_prices),0)  如果商品没有销售时,销售额显示为0
  • 统计后过滤
    • 统计每一个客户购物的总开销
SELECT
	u.user_name,
	IFNULL( sum( og.goods_numbers * og.goods_price ), 0 ) AS amount 
FROM
	( ecs_order_info oi INNER JOIN ecs_order_goods og ON oi.order_info = og.order_id )
	RIGHT JOIN ecs_users u ON ou.user_id = u.user_id 
GROUP BY
	u.user_name;
    • 哪些类型的商品平均价格超过了2000
SELECT
	gt.cat_name,
	AVG( g.market_price ) 
FROM
	ecs_goods_type gt
	LEFT JOIN ecs_goods g ON gt.cat_id = g.goods_type 
GROUP BY
	gt.cat_name 
HAVING
	AVG( g.market_price ) > 2000;
    • 哪些类型的商品平均价格超过了所有产品均价 group by 与having
SELECT
	gt.cat_name,
	AVG( g.market_price ) 
FROM
	ecs_goods_type gt
	LEFT JOIN ecs_goods g ON gt.cat_id = g.goods_type 
GROUP BY
	gt.cat_name 
HAVING
	AVG( g.market_price ) > ( SELECT avg( market_price ) FROM ecs_goods );
    • 列出总销售额超过10000的商品信息
SELECT
	og.goods_name,
	sum( og.goods_price * og.goods_number ) 
FROM
	ecs_order_goods og 
GROUP BY
	og.goods_name 
HAVING
	sum( og.goods_price * og.goods_number ) > 10000;
    • 有多少个订单只购买了一种商品
SELECT
	count( * ) 
FROM
	( SELECT order_id, count( goods_id ) FROM ecs_goods GROUP BY order_id HAVING count( goods_id ) = 1 ) t;#注意要给虚拟表加别名

4.DML

数据操作语言,插入,删除,更新数据库中的数据表

4.1 insert

- 插入一条记录
insert into  表名(c1,c2,c3...) 
values(v1,v2,v3...)#顺序,类型,个数;插入的值要和列名顺序相对应
-  插入多条数据
insert into  表名(c1,c2,c3...) 
values(v1,v2,v3...),
(v1,v2,v3...),
(v1,v2,v3...);
-  不指定插入列,表名插入所有列
insert into  表名 
values(v1,v2,v3...)

复制表:将a表中的数据复制到b表中

insert into b
select * from a

快速备份表

create table b
as select * from a;

4.2 update

语法

update  tab_name
set col_name=new_value,col_name=new_value......
where search_condition;
修改用户zhangsan的密码和用户名
update ecs_users
set password='123345',qq='10000'
where user_name='zhangsan'

4.3 delete

语法:

delete from tab_name
where search_condition;
删除zhangsan用户
delete from ecs_users
where user_name='zhangsan';

参考链接:
https://study.163.com/course/courseMain.htm?courseId=1005821015

你可能感兴趣的:(sql)