sql笔记本

Posted JimCarter

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql笔记本相关的知识,希望对你有一定的参考价值。

文章目录

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 INNOT 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中使用ISNULLNULLIF函数。

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层。
常用格式有三种:

  1. WHERE xxx [NOT] IN (子查询)
  2. WHERE xxx >/< [ANY/ALL] (子查询)
  3. 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笔记本的主要内容,如果未能解决你的问题,请参考以下文章

SQL课堂笔记--Access

sql索引创建

MySQL笔记:数据类型

ORACLE DG 主备库开启与关闭顺序

sql 保留2位小数

求教,sql保留2位小数