sql笔记本
Posted JimCarter
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql笔记本相关的知识,希望对你有一定的参考价值。
文章目录
- 1. 查询
- 2. INSERT
- 3. UPDATE
- 4. DELETE
- 5. 常见操作
1. 查询
1.1 计算列:支持加减乘除,%求余
select (a+b) as 'value' from table //如果a和b是字符串,则表示拼接
select (a*b-c*d)/e as 'value' from table where a<>0 //不等于
select (a+30) as 'value' from table
//char 2 表示两位,空余部分补全。
select convert(char(2),sale_count)+'个' as 数量,convert(char(8),sale_price)+'元' as 价格 from table
select 1+1 as '结果','aaa'+'bbb' as '组合' from table
1.2 特殊的比较运算符
!> 不大于
!< 不小于
<>或!= 不等于
1.3 范围查询,[between a and b
] 和 [not between a and b
]
其中a需要小于b,实质查询条件是>=a,<=b的数据。
select * from table where a between 4 and 8;
select * from table where t between '2018-04-05' and '2019-05-06'
select * from table where t between DATEADD(DAY,-1,GETDATE()) and GETDATE(); //查询24小时内的值,GETDATE()返回 2021-12-27 21:13:48.610
同理还有not between a and b
1.4 日期查询处理
//查询2010年更新,且10月pub的数据
select * from table where MONTH(pubdate)=10 and YEAR(update)=2010;
//查询指定日期
select o.DataSource,o.CreatedTime from [order] o where o.DataSource like '%Sen%' and o.CreatedTime>=CAST('2021-12-10 00:00:00 +07:00' as datetimeoffset) and o.CreatedTime<CAST('2021-12-11 00:00:00 +07:00' as datetimeoffset) order by o.CreatedTime
★计算间隔天数:DATEDIFF(pattern,startdate,enddate).
其中patter的值为: Year(Yy,yyyy),Quarter(Qq,q),Month(Mm,m),Dayofyear(Dy,y),Day(Dd,d),Week(Wk,ww),Hour(Hh),Minute(Mi,n),Second(Ss,s),Millisecond(ms)。
select DATEDIFF(day,a,b) as '间隔天数' from table
★DAY(date)
函数
计算date的天,假如date是2019-05-12,则返回13。如果DAY(0),则返回1,因为0表示1900-01-01
同理还有MONTH(date):仅对1753年1月1日之后的日期有效。
还有Year(date):仅对1753-9999之间的年份有效。
★日期格式化输出,使用CONVERT函数
select CONVERT(VARCHAR,GETDATE(),108) as showtime
108:表示格式为:hh:mm:ss
120:yyyy-mm-dd hh:mi:ss(24h)
102:yy.mm.dd
mysql使用DATE_FORMAT(date,format)
函数
ORACLE使用TO_CHAR(date,'YYYY-MM-DD')
1.5 IN
与 NOT IN
查询
select * from table where a IN ('OPPS','VIVO','BBG');
select * from table where price IN (600-100,600,600+100);//查出价格为500,600,700的数据。
select * from table where 600 IN (price,discount);//查询出price和discount等于600的数据。
1.6 类型转换 CAST(value AS type)
type可以是int、
例如:
select CAST('123' as int);select CAST(236.3 as int) //会舍弃小数位非四舍五入。
select CAST('23.6' as decimal(9,3)) //转为总长度为9,小数位为3的decimal。decimal默认总长度为18,精度为0,会四舍五入。
1.7 去除多余空格trim
函数:LTRIM(value0)
select LTRM(a) from table
1.8 通配符查询
%
:略_
:略[]
:表示范围,只有MSSQL和Access支持。where a like '[mr]%'
:a是m或r开头。where a like '[a-e]%'
:a是a到e开头。where a like '^[mr]%'
:a不以m或r开头。
1.8.1 转义字符 ESCAPE
如果想匹配%怎么办?使用ESCAPE。 where a like '%10#%' ESCAPE '#'
:表示查找以10%结尾的数据,井号后面的字符会被认为是普通字符,当然你也可以把井号改为更常见的右斜线。
select email like '%\\_%'
;搜索email里包含下划线的数据。
1.9. 行查询
1.9.1 查询指定行,如第6行的数据
select id,name,price from (select top 6 * from goods) aa
where NOT EXISTS (select * from (select top 5 * from goods) bb where aa.id==bb.id)
1.9.2 查询随机的一行
SQL Server中使用NEWID()
函数:
select top 1 * from goods order by NEWID();
MySQL中使用RAND()
函数:
select * from goods order by RAND() limit 1;
Oracle中使用DBMS_RANDOM.VALUE()
函数。
1.9.3 添加行号
select (select COUNT(id) from goods A where A.id>=B.id) as 编号,id,sn,amout
from goods B order by 1;
1.9.4 查询从第x行-第y行的数据
//查询第3-6行间的数据
select 编号,ISBN,BookName from (select ROW_NUMBER() OVER(ORDER BY ISBN) as 编号,ISBN,BookName from table) a where a.编号 BETWEEN 3 AND 6
//查询奇数行的数据(MSSQL)(求余)
select 编号,ISBN,BookName from (select ROW_NUMBER() OVER(ORDER BY ISBN) as 编号,ISBN,BookName from table) a where a.编号%2=1
1.10 空值处理
1.10.1 判断是否为NULL
select * from table where name IS NULL.
select * from table where name IS NOT NULL.
1.10.2 空值处理ISNULL
//如果age为null,则默认为10。否则ISNULL会返回原值
select ISNULL(age,10) as newage from table
Oracle中使用NVL()
函数:NVL(data,replace_with)
:如果data为NULL,则返回replace_with,否则返回data原本的值,data与replace_with需为同一种类型。支持数字、字符串、日期格式。
MySQL中使用ISNULL
或NULLIF
函数。
1.11 数据排序
理论上select返回的结果是无序的,他们之间的顺序主要取决于物理位置。
不同数据库中orderby 后面可以跟的列的数量是不同的,Oracle是255列。
oracel中没有top关键字,等效的是rownum属性,会为查询每一行分配一个行号,如1,2,3…。
当你想查询行号大于N的时候,这个属性不能在where里直接使用,需要使用子查询。如:
select * from (select rownum as no,name,age from table) where no>2.
但是如果想查询行号小于N的时候,则可以在where里直接使用:
select * from table where rownum <3.
(因为oracle把查询到的第一个符合条件的结果的行号标位1,第二个标位2. 很奇葩,参考:https://blog.csdn.net/qq_39196949/article/details/84379874)
1.11.1 还有按拼音/笔画排序的
需要使用COLLATE
,需要使用字符集。
1.12 数据分析
1.12.1 聚合函数SUM(),AVG(),COUNT(),MAX(),MIN()
SUM(distinct column)
:对非空值求和,只支持数字
select SUM(distinct price1) from table.
select SUM(price1-price2) from table.
AVG
:只支持数字,对非空值求平均,非NULL值的和除以非NULL值的数量。
//real可以过滤掉末尾所有的0
select CAST(AVG(price1+price2) as real) as 平均值 from table
//distinct可以过滤掉重复的值,不参与计算
select AVG(distinct price1) from table
-
MIN/MAX
:支持数字、字符、日期 -
COUNT([distinct]*)
:统计行数,最大支持21亿行
count(*)
与count(price1)
的区别:*
会统计NULL值,而具体制定某个列名的话,会忽略NULL值。count(distinct *)
会出错,因为*
就表示了要统计所有的行,而不管它是不是NULL。
//使用distinct:过滤重复的和NULL。流程:首先获取所有非空的数据,然后再过滤重复的数据。
select count(distinct price1) as 不重复的价格 from table
1.13. 分组:Group By、Where、Having
1.14. 子查询
最多可以嵌套32层。
常用格式有三种:
WHERE xxx [NOT] IN (子查询)
WHERE xxx >/< [ANY/ALL] (子查询)
WHERE [NO] EXISTS(子查询)
1.14.1 列中的子查询
//返回值只有一列:
select a,b,(select max(price) from tableB where tableA.Id=tableB.Id) from tableA
//返回值有多列:
select a,b from tableA where(a,b) IN (select MAX(a),b from tableB GROUP BY b);
IN 和 EXIST的区别????
1.15 表连接
JOIN
关键字左边的表示左表,右边的表示右表。
1.15.1 内连接(JOIN
)默认就是INNER JOIN
- 等值连接(使用=):
select a,b from tableA,tableB where tableA.a=tableB.a;
//等同于显式写法
select a,b from tableA [INNER] JOIN tableB on tableA.a=tableB.b;
- 不等值连接(使用
>,>=,<=,<,!>,!<,<>
):
select a,b from tableA aa INNER JOIN(select * from tableB where name='xx') bb ON aa.a<>bb.b
- 连接多个表:sql不会限制一条查询中可以连接的表的数量,所以可以连接多个表
select * from tableA,tableB,tableC where tableA.id=tableB.id AND tableA.type=tableC.id
1.15.2 外连接:左连接、右连接、全连接
LEFT JOIN
RIGHT JOIN
FULL JOIN
1.15.3 交叉连接:CROSS JOIN
是笛卡尔乘积的另一个名称,会将A表的每一行与B表的每一行进行比较,不需要ON关键字
select a from tableA CROSS JOIN B;
1.15.4.组合查询(UNION
)
使用要求:必须由两个或两个以上的SELECT语句组成,语句之间使用UNION分隔。每个SELECT语句中的列的数目必须相同,且数据类型必须相同或者兼容。
使用UNION合并结果集:
select a,b,c from tableA where id in (12,13) UNION select a,b,c from tableB where name like '%xxx%'
会将两个select的结果集去重之后合并。如果不想去重则使用UNION ALL
2. INSERT
-
多行:
INSERT INTO tableA (Col1,Col2) VALUES('a','b'),('c','d'),('1','2')
-
查询出来之后再插入:
INSERT INTO tableA select * from tableB where name like '%a%'
;(虽然要求两个表的结构需要一致,但是并不要求列名匹配。)要求tableA事先已经创建好。 -
复制表数据:
SqlServer使用SELECT INTO
语句:select a,b,c INTO newTable from tableA where id>6
; 其中newTable不要求事先已存在。
Oracle和MySql中使用CREATE TABLE SELECT
语句:create table newTable select a,b,c from tableA where id>6;
3. UPDATE
update tableA set Col1='a',Col2='b' where xxxx;
没有where条件的话,表示更新所有。
4. DELETE
如果用来删除整个表的数据时,建议使用TRUNCATE TABLE tableA
语法,效率更高。
5. 常见操作
5.1 查看数据库占用空间
//配置信息
use information_schema
//查询整个库占用的空间
select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES
//查询每个表占用的空间
select
table_schema as '数据库',
table_name as '表名',
table_rows as '记录数',
truncate(data_length/1024/1024, 2) as '数据容量(MB)',
truncate(index_length/1024/1024, 2) as '索引容量(MB)'
from information_schema.tables
order by data_length desc, index_length desc;
5.2 查看每日每小时数据量
select date_format(t.CreateTime,'%Y-%m-%d %H') as hourdate,count(1)
from order_info t
where t.CreateTime>=cast('2022-05-26 00:00:00 +08:00' as datetime) and t.CreateTime<=cast('2022-05-26 23:59:59 +08:00' as datetime)
group by hourdate
以上是关于sql笔记本的主要内容,如果未能解决你的问题,请参考以下文章