mysql中DQL操作

查询语句语法结构

select [字段名],[函数(字段名)]
From 数据表名
[连接]
[where子句条件判断]
[group by分组]
[having 二次筛选]
[order by 字段名]
[limit x,x]
[offset x];

简单查询

--1查询所有字段所有数据
    select * from 数据表名;
    select * from sale; -- * 代表所以字段
-- 2 查询部分字段数据
		-- select 字段名称,字段名称2,字段名称3 from 数据表名 
		-- 查看销售表中的订单编号,产品编号,数量
       select order_id,product,number from sale;
		
			-- 列题1:想要看评分和播放量的情况
			SELECT `播放量`,`评分`from `爱奇艺视频数据`;
			
			-- 列题2:想要看电视剧的演员与电视剧的类型
			SELECT `演员`,`类型` from `爱奇艺视频数据`;

sql语句中进行简单算术 + - * / %,where

         --  1 :+ - * / %
		-- SELECT 字段名称,字段名称2,字段名称2*0.8 from 数据表名
		-- 电商活动,所有商品8折优化,计算所有商品的单价
        SELECT order_id,product,number,number*0.8 from sale;
			-- 查看电视剧的好评率
			SELECT * ,`好评数`/`评分人数` 好评率 from `爱奇艺视频数据` ;-- 好评率是取的别名
			添加条件筛选数据
		-- 对数据按照条件进行查询需要使用where子句添加逻辑条件判断
        SELECT *from 数据表名 where 字段名 = 4;
		-- 2 :简单逻辑判断
			-- > >= < <= = !=
			-- 查看4号销售员卖出去的所有订单
            SELECT *from sale where salesman = 4;
			
				-- 想要看评分和播放量的情况,并且没完结的不看
				SELECT `评分`,`播放量`,已完结  from `爱奇艺视频数据` WHERE `状态` = '已完结';
				-- 想要看电视剧的演员与电视剧的类型,并且出过两季以上
				SELECT `演员`,`类型`,`总集数` from `爱奇艺视频数据` WHERE `总集数`>=2;

区分大小写查询

-- mysql默认不区分大小写,需要在条件字段前添加binary关键字支持区分大小写
select * from sale where order_id="YD19004"select * from sale where binary order_id="YD19004"-- binary区分大小写,

多条件

and 和
			-- 1.多条件and--多个条件必须同时满足
			-- 查询4号销售员卖的所有的XXXXX商品的订单
       	   SELECT * from sale where salesman = 4 and product = 8605001;
				-- 2.想要看评分和播放量的情况,并且没完结的不看、播放量大于100000000
				SELECT `评分`,`播放量` from `爱奇艺视频数据` WHERE `状态` = '已完结'and `播放量` >100000000;
or 或者
            --  1. 多条件or--多个条件只需要满足其中一个
			 SELECT * from 数据表 WHERE 字段名 条件 or 条件;
			-- 查询4号或者9号销售员买出去的所有订单
            SELECT * from sale where salesman = 4 or 9;-- or
				-- 想要看评分和播放量的情况,只看08年或12年上映的
				select `评分`,`播放量`,`上映时间` FROM `爱奇艺视频数据` where `上映时间`=2008 or `上映时间`=2012;
like模糊匹配
-- 使用like进行模糊查询,模糊的对字段进行匹配,%标识任意个任意字符
			-- 判断开头:前面不加%
			-- 判断结尾:后面不加%
			-- 查询所有的zh开头的订单
      -- like 一定搭配通配符使用
      --  匹配一个字符的通配符是_   like "%于正_"  输出结果 于正化/于正思	
				-- 想要看评分和播放量的情况,只看喜欢的演员演的
				SELECT * from `爱奇艺视频数据` where 演员 like "%胡歌%";
				
				-- 想要看语言\地区\简介,只看悬疑剧且超清的
				SELECT `语言`,`地区`,`简介`,`类型` FROM `爱奇艺视频数据` WHERE `类型` LIKE "%悬疑%" and 类型 like "%超清%";
				SELECT `语言`,`地区`,`简介`,`类型` FROM `爱奇艺视频数据` WHERE `类型` LIKE "%悬疑%/%超清%";
				
				-- 想要看评分\播放量\总集数,并且只看喜欢的导演于正和其他导演的电视剧
        SELECT 评分,播放量,总集数,导演 from `爱奇艺视频数据` where 导演 like "%于正/%" -- 输出于正/xxx/xx
NULL判断
			-- is null 判断为空的数据
			-- is not null判断不为空的数据
			-- 查询所有单价为空的产品
         SELECT * from product where PRICE is not;
			
				-- 查询出所有演员为空的电视剧
				SELECT * from `爱奇艺视频数据` where 演员 is null;
				
				-- 查询所有演员不为空的电视剧
				SELECT * from `爱奇艺视频数据` where 演员 is not null;
between与not
-- 介于与不介与使用between与not
			
			SELECT * from 数据表名 where 字段名 not between 条件 and 条件;-- 不介与
			SELECT * from 数据表名 where 字段名 between 条件 and 条件;-- 介于
			
			-- 查询1-5号销售员卖出去的所有订单
      SELECT * from sale where salesman  not between 1 and 5;
			
      SELECT * from sale where salesman  between 1 and 5;    
in()与not in(
       -- 查询所有的组长卖出去的订单
        SELECT * from sale where salesman in(1,6,13);
   	    SELECT * from sale where salesman not in(1,6,13)
		
				-- 查询出所有的国产剧\美剧\韩剧
				SELECT * from 爱奇艺视频数据 where 类型 in(国产剧,美剧,韩剧);
				
				-- 查询出所有不包括05年\08年\12年的电视剧
				SELECT * from 爱奇艺视频数据 where 上映时间 in(05,08,12);
				
起别名
 -- SELECT 原字段名 新字段名 from 数据表名;
	        -- 将销售员的每个字段都改成中文
			SELECT 好评数/评分人数 好评率 from `爱奇艺视频数据`;-- 第一种方法
			SELECT 好评数/评分人数 as 好评率 from `爱奇艺视频数据`;-- 第二种方法
			

函数

单行函数
数值函数
        select abs(-45) 取绝对值, -- 取绝对值      输出:45
			   ceil(9.001)  向上取整,-- 向上取整   输出:10
			   floor(8.9999) 向下取整,-- 向下取整  输出:8
			   round(9.45678) 四舍五入 -- 四舍五入 输出:9
		 from dual -- dual 虚拟表
字符串函数
-- 常用的有小写,大写,计算长度、截取部分字符串、字符串拼接
    select
		lower("ABCD") 大写转小写, -- 大写转小写 输出:abcd
        upper("abcd") 小写转大写, -- 小写转大写 输出:ABCD
		length("中国") 计算字符串长度,-- 计算字符串长度 输出:6 (一个中文是3个字符)
		-- left()   right()
		substr("四川成都",3,2)截取部分字符,-- 3,第几位 2,截取几位,输出:成都
		concat("中国","成都") 字符串拼接 -- 字符串拼接 输出:中国成都
日期与时间函数
        -- curdate()年月日
		-- curtime()时分秒	
		-- now()年月日时分秒 当前语句执行的时间
		-- sysdate()年月日时分秒 当前函数执行的时间
		-- sleep(3)表示暂停,括号内写数值,单位为秒,上例意思就是查询的时候暂停3秒
		-- 虽然可以表示年月日时分秒,但是插入数据的时候,还是要参照表的结构
		-- date_format(date, "%Y-%m-%d")
		-- date_add(date, interval expr type) 原时间加一个日期
		-- date_sub(date, interval expr type) 原时间减一个日期
		-- datediff(date1, date2) 两日期之间相隔天数
        select curdate(),curdate(),now(),sysdate() 
		 SELECT NOW(),SYSDATE(),SLEEP(3),NOW(),SYSDATE() -- sleep(3) 代表运行暂停3秒
		 select date_format(date,"%Y年%m月%D月") from sale; -- 大写%D 输出是英文th,-- d小写是中文 月
		 -- date_format()取出来的数据是字符串
		 select month(date) from sale;
		
		 -- month year 1 day 取出来的数据是数字 
		 select date,date_add(date,interval 5 day)from sale;-- intervsal 5 day代表添加天数
		 select date,date_add(date,interval 2 year)from sale;-- interval 2 year 代表添加多少年
		 
		 select date,
		 date_add(date,interval 10 day),-- 日期加运算
		 date_sub(date,interval 10 year)-- 日期减运算
		 from sale;
		 
		 select datediff("2022-10-31","2021-10-30") -- (相差天数)第一个日期减第二个日期 输出:366
        select abs(datediff("2020-10-31","2021-10-30")) 

			-- 商品毛利率毛利额/销售额四舍五入取整,并且算出毛利率(百分比)
			select concat(round(毛利额/销售额*100, 2),"%")from `商品_毛利率`
		

多行函数/聚合函数
-- 查看销售记录表中number字段的最大值,最小值,求和,平均值与计数
select max(number) 最大值,
       min(number) 最小值,
	   sum(number) 求和,
	   avg(number) 平均值,
	   count(number) 计数 -- 计算所有非空值的数量
 from sale;

SELECT count(`数据获取日期`),
      count(`演员`),
			count(*),-- 如果所有字段都为空,则不计算
			count(1) -- 只要有一条记录,那么对1计数一次
 from `爱奇艺视频数据` 

条件判断函数

if判断
-- 销量数据表,number大于200为达到满减,其他为小额订单
      select *,if(number>200,"达到满减","小额订单")from sale;

case—end判断
	-- 1,根据电视剧评分,将电视剧分为封神、值得推荐、下饭视频
     SELECT 整理后剧名,评分,
		 case
		 when 评分>=9 then "封神"
		 when 评分>=7 then "值得推荐"
		 else "下饭视频"
		 end type-- type新建字段起的别名
		 from `爱奇艺视频数据` 

--2,销售分组表,销售三组发奖金,销售一组扣绩效
     select *,
		 case team -- team字段
		 when "销售三组" then "发奖金"
		  when "销售一组" then "扣绩效"
			else team -- 等于他本身的值team
			end type -- type给字段起的别名
			from salesman
窗口函数排名
    -- rank函数:如果有并列名次的行,会占用下一名次的位置,输出结果:1,1,1,4。
	-- dense_rank函数:如果有并列名次的行,不占用下一名次的位置。输出结果是:1,1,1,2
	-- row_number函数:不考虑并列名次的情况。输出结果是:1,2,3,4
	-- <窗口函数> over (partition by <用于分组的列名> order by <用于排序的列名>
	-- 对成绩表按科目进行成绩排名
        select *,
				rank() over(
				partition by cid -- 用于分组的列
				ORDER BY score desc -- 用于排序的列名
				) 排名--  代表取的字段名称
				from sc 
				
				 select *,
				dense_rank() over(
				partition by cid 
				ORDER BY score desc 
				) 排名2 --  代表取的字段名称
				from sc 
				
				 select *,
				row_number() over(
				partition by cid 
				ORDER BY score desc 
				) 排名3 --  代表取的字段名称
				from sc 
				
				-- 查看成绩表的累积和
              select *,
			  sum(score) over(
				partition by cid -- 分组依据
				ORDER BY score desc 
				) 求和
				from sc 
去重
-- 对查询出来的数据进行去重
	-- distinct
	-- 查看sale表中所有的销售员有哪些
  SELECT distinct salesman from sale;
	SELECT count(distinct product) from sale; 
分组group by
-- group by
	-- 按条件进行对数据进行分组,可以完成数据的统计
	-- 1 单个字段进行分组
		-- 统计sale表中每一个销售员卖出去多好订单
		 SELECT salesman,COUNT(*) 订单量
		from sale
		GROUP BY salesman  -- 各个分组里的计算
		
      SELECT salesman,COUNT(DISTINCT order_id)订单量
		from sale
		GROUP BY salesman

	-- 2 多个联合分组
		-- 统计sale表中每一个销售员每种产品卖了多少个
        select salesman,product,sum(number) 数量
		from sale
		GROUP BY salesman,product

-- 爱奇艺数据统计每一年多少部悬疑剧上映
		select 上映时间, count(1) 数量
		from `爱奇艺视频数据`
		where `类型` like "%悬疑%"
		group by 上映时间
-- 餐饮数据统计每种菜有多少加餐厅,平均人均消费多少元
		select 类别, count(1) 餐厅数量, avg(`人均消费`) 平均人均消费
		from `上海餐饮数据`
		group by 类别
二次筛选having
-- having
	-- 对where子句查询出来的结果进行二次过滤筛选
	-- 统计所有销售员中卖出去的产品数量超过1000的员工有哪些
    SELECT cid,avg(score)平均分
    from sc
    group by cid
    having 平均分>70;
	
		-- 爱奇艺数据统计每一年有多少部电视剧上映,并且上映电视剧超过1000部的年份有哪些
		select 上映年份 -- , count(1) num
		from `爱奇艺视频数据`
		group by 上映年份
		having count(1)>1000
排序order by
	-- asc 升序  desc 降序
	-- 统计每个销售员卖出去的所有产品的数量,并进行降序排序
     SELECT salesman,product,number
	 from sale 
	 order by number DESC
	
		-- 爱奇艺数据查看喜欢的演员演的电视剧,按评分进行降序排序
		SELECT *,
		 rank() over(
		 partition by `剧名`
		 order by 评分 DESC
		 )排名
	    from `爱奇艺视频数据` -- 排名
 
分页limit
    -- 查询第N页的数据limit公式为(n-1)*count
	-- 统计每个销售员卖出去的所有产品的数量,并降序排序,取前3名销售员
select salesman,sum(number)snum
from sale
GROUP BY salesman
ORDER BY snum desc
limit 0,3;-- 第一个参数0代表跳过前几个数,第二个参数3,代表取几个数为一页
-- 取第n页的内容:(n-1)*count,count

		-- 爱奇艺数据查看喜欢的演员播放量前三的电视剧有哪些
		select `整理后剧名`,`演员`,sum(`好评数`)
		from `爱奇艺视频数据`
		where 演员 like '%杨幂%'
		group by `整理后剧名`,`演员`
		order by 好评数 desc
		limit 3,2 
跳过N条数据 offset
-- offset
	-- 查询指定的第几条数据的时候可以使用limit配合offset来使用
	-- limit y offset x 分句表示: 跳过 x 条数据,读取 y 条数据
	-- 统计每个销售员卖出去的所有产品的数量,并降序排序,取前3至6名销售员
select salesman,sum(number)snum
from sale
GROUP BY salesman
ORDER BY snum desc
limit 3
offset 9;-- 跳过9,取3为一页

多表连接查询

内连接 using子句\on子句
-- 1 using子句
			-- 需要指定关联字段名,且字段名必须相同。
			/*
			select column1,column2,column3
			from table1
			 join table2 
			using (column);
			*/
			-- 查询product表中每个产品对应的品牌名称
            SELECT *
			from product
			join brand
			using(brand_id);-- 链接二个表,合并表
			
			-- 查询00072-口品牌的所有产品有哪些
			SELECT *
			from product
			join brand
			using (brand_id)
			WHERE brand_id=00072;
-- 1 on子句
			-- 需要指定关联字段名,但是字段名可以不相同。
			/*
			select t1.col1,t1.col2,t2.col1
			from table1 t1
		    join table2 t2 
			on (t1.col = t2.col);
			*/
		/*	select *
        from  数据表1  取的别名s
        join  数据表2  取的别名ss
        on  别名. 数据表1字段= 别名.数据表2字段*/ -- 链接二个表
			
			-- 查询sale表中每张订单的销售员姓名
         select *
		 from sale s-- s取的别名
		 join salesman ss
		 on s.salesman = ss.id
		
			-- 统计二组每个销售员卖出的订单数量总合
			 SELECT salesman,sum(number) snum
			from sale s
			join salesman ss
		    on s.salesman = ss.id
			WHERE team = "销售二组"
			GROUP BY salesman
			
			-- 统计每个月订单销售产品数超过100的订单数量总和
			SELECT month(date)mon,sum(price*number)销售额
			from sale s
			join product p
			on s.product = p.product_id
			GROUP BY mon

外连接
                union -- union的作用就是取并集,并去重
				union all -- union all的作用就是取并集但是不去重
		-- 1 左外连接
			/*
			select t1.col1,t1.col2,t2.col1
			from table1 t1
			left [outer] join table2 t2 
			on (t1.col = t2.col);
			*/
			
			-- 查询每一个品牌旗下的每一种商品,需要保留所有的品牌信息
     SELECT * from brand b left join product p
	 on b.brand_id = p.brand_id
	 union all
  
	SELECT * from brand b right join product p
	 on b.brand_id = p.brand_id
		-- 2.右外连接
			/*
			select t1.col1,t1.col2,t2.col1
			from table1 t1
			right [outer] join table2 t2 
			on (t1.col = t2.col);
			*/
		
	-- 查询每一个品牌旗下的每一种商品,需要保留所有的品牌信息
			select *
			from product p 
			right join brand b
			on p.brand_id = b.brand_id
			where p.product_name is null

		-- 3 全外连接
			/*
			select t1.col1,t1.col2,t2.col1
			from table1 t1
			full outer join table2 t2 
			on (t1.col = t2.col);
				MySQL不支持全外连接,可以使用左右外连接取并集的方式实现同样的效果
				
			*/

自然连接natural join
-- 查询出来的结果是所有能匹配上的数据。取交集。
	-- 自动根据相同字段名,将所有能匹配的数据进行连接。
	-- 如果没有指定需要查询的字段,会遍历所有表中的所有字段,执行效率低。
	/*
	select column1,column2,column3
	from table1
	natural join table2;
	*/
	-- 查询product表中每个产品对应的品牌名称
    select *
	from product
	natural join brand;

交叉连接cross ioin
	/*
	select column1,column2,column3
	from table1
	cross join table2;
	*/
	-- 查询product和brand表能匹配到的所有可能
    select * 
	from sc
	CROSS join df -- 第一种方法
	
	 select * 
	from sc,df -- 第二种方法
自连接
	-- 自己关联自己,需要一张表中的一个字段与另一个字段有关联。
	/*
	select t1.col1,t1.col2,t2.col1
	from table1 t1
	join table1 t2 
	on (t1.col = t2.col);
	*/
	-- 查询每个组员的组长的姓名
    select *
	from salesman s1
	join salesman s2
	on s1.mgr = s2.id

多表连接join on
	-- 三张及以上表格连接查询的时候,其实可以当做前两张表查询的结果再与第三张表进行连接查询。
	/*
	select t1.col,t1.col,t2.col,t3.col
	from table1 87865068
	join table2
	on (t1.col = t2.col)
	join table3
	on (t1.col = t3.col);
	*/
	-- 查询每个销售员的姓名与销售金额总和
    -- (拆分) salesman表里的 姓名
	-- 销售金额 单价*数量
	-- 单价 来自product表
	-- 数量 来自sale表
SELECT ss.name, sum(price*number) 金额
from sale s
join salesman ss
on s.salesman = ss.id
join product p
on s.product = p.product_id
GROUP BY ss.name

-- 查询销售订单中数量大于1000的订单编号、销售员名称、销售日期、数量、金额
select order_id,name,date,number,price*number amount
from sale s
join salesman ss
on s.salesman = ss.id
join product p
on s.product = p.product_id
where number > 1000

-- 查询每个产品对应的品牌名称与销售数量总和及销售金额总和
SELECT s.product,b.brand_name,sum(number) s_num,sum(number*price) amount
FROM sale s
join product p
on s.product=P.product_id
join brand b
on s.brand = b.brand_id
GROUP BY s.product

子查询

-- 一个查询语句嵌套在另一个SQL语句内部的查询,
    -- 不相关子查询 子查询可以单独运行 
		-- 单行子查询 子查询的结果只有一个值
		 -- 查询sale表中所有订单数量超过平均数的订单的数量
         select count(distinct order_id)
		 from sale
		 where number > (SELECT avg(number) from sale )

		-- 多行子查询 子查询的结果是一个列表
		-- 查询sale表中各个组长卖出去的订单的数量
        select salesman,count(distinct order_id) 订单数量
		from sale 
		where salesman in(SELECT id from salesman where mgr=0)
		GROUP BY salesman

		-- 子查询的结果作为一个新的表,子查询的结果必须起别名
		-- 找出销售数量前三名的员工的姓名
        -- 拆分:找出销售数量前三名的员工的姓名
		 -- 先算出每一个销售员销量的数量
		  -- 找前三名
     SELECT *
	   from (
	       SELECT *,
		   DENSE_RANK() over(
		   order by s_num desc
			 ) ranking
		   from(
			     SELECT salesman,sum(number) s_num
				 from sale
				 GROUP BY salesman)t1)t2
	 where ranking <=3

相关子查询

   -- 相关子查询
	-- 子查询不能独立运行
	-- sc表中,每一科超过平均分的学生
  SELECT * from sc where  cid =1 and score > (SELECT avg(score) FROM sc WHERE cid = 1) 
	UNION
	SELECT * from  sc where   cid =2 and score > (SELECT avg(score) FROM sc WHERE cid = 2) 
		UNION
	SELECT * from  sc where  cid =3 and score > (SELECT avg(score) FROM sc WHERE cid = 3);

SELECT * FROM sc s where score >(select avg(score) from sc where s.cid = cid)

-- 查询订单数量大于平均值的订单信息
SELECT *
from sale
where number >(SELECT avg(number) from sale)

通用表达式 with as

	-- 通用表表达式(CTE)是一个在语句级别定义的临时结果集。
	-- 作用范围是当前语句,CTE可以理解成一个可以复用的子查询
	-- 当然跟子查询还是有点区别的,CTE可以引用其他CTE,但子查询不能引用其他子查询
	-- with 通标表达式名 as (查询语句)
	-- 定义多个通用表达式的时候,前一个通用表达式与后一个通用表达式之间用逗号隔开
	-- with 只需要写一次

with cte1 as(  
     SELECT salesman,sum(number) s_num from sale GROUP BY salesman),
		 cte2 as(
		 select *,
		 DENSE_RANK() OVER(
		 order by s_num desc) ranking
		 from cte1)
     SELECT *from cte2 where ranking<=3;



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值