0. SQL细节要点

Posted Mrs.King_UP

tags:

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

语法结构:select->from->where->group by->having->order by->limit
运行顺序:from->where->group by->having->order by->limit->select

  1. like用于where中,进行字符串匹配,%匹配0、1、多个字符 ,_表示一个占位符

  2. in 类似于多个or,筛选出字段值介于()之中

  3. between v1 and v2 字段值介于两个值之间,且包含两个值(not between v1 and v2不介于两者之间)

  4. order by对结果集按照某个字段进行排序,默认asc升序,desc为降序

  5. create table 表名(
    字段值 字段数据类型 约束

    这里的约束可能是主键约束primary key、非空约束 not null, 唯一值约束unique

  6. insert into 表名(字段1,字段2,。。。) values(值1,值2,。。。)
    如果插入的值的顺序和表中字段的顺序一致,表名后的字段顺序可以去掉;如果只插入部分字段or插入值的顺序和表中定义的字段顺序不一致,则不可省略字段

  7. update 表名 set 字段值1=值1,字段值2=值2 where 条件
    用于更新表中的记录,where条件用于指明更新那一条记录,如果不加where,则更新所有记录的字段值

  8. delete from 表名 where 条件
    删除表中的记录,where条件指明删除的某条记录

  9. create index in_name on employees(name);
    创建索引,提高访问速度

  10. 视图是基于SQL语句结果集的可视化表,修改视图,同时底层的表中的数据也会被修改
    create view 视图表 as select 字段名 from 表名 where 条件;

  11. null的判断通过is null 或者is not null,不能用=,!=

  12. 为表名和字段名使用as起别名,as可以省略

  13. join基于两个表之间的共同字段建立连接的一种方式
    内连接:列出两个表中都存在的记录
    左连接:即使没有匹配也列出左表中的所有记录
    右连接:即使没有匹配也列出右表中的所有记录
    select 字段名 from 表1 join 表2 on 表1.字段1=表2.字段2 where子句
    (on后可以跟多个连接条件,用and连接)

  14. order by
    select winner,subject
    from nobel
    where yr=1984
    order by subject in(‘chemistry’,‘physics’), subject,winner;

  15. limit限制最后展示出的行数,写在最后
    (取前3个)
    order by area asc
    limit 3
    (取第4到第7)
    order by area asc
    limit 3,4(limit x,n从第x+1行开始返回n行),跳过3条数据取出4条
    limit 1 offset 2 从第2条数据(不包括)开始,取出1条数据

  16. 以下的两种方式均表示取2,3,4三条条数据。
    1.select* from test LIMIT 1,3;
    当limit后面跟两个参数的时候,第一个数表示要跳过的数量,后一位表示要取的数量。

    2.select * from test LIMIT 3 OFFSET 1;(在mysql 5以后支持这种写法)
    当 limit和offset组合使用的时候,limit后面只能有一个参数,表示要取的的数量,offset表示要跳过的数量 。

  17. 聚合函数
    max()、avg()、min()、sum()
    count(*)计算行数;count(字段名)计算非NULL行数

  18. group by 字段名
    先按照字段名分组(此时对字段名去重);然后对表按照字段名分区;分区之后,根据聚合函数聚合相应的列;填充到分组之后
    continents count(name)

19.常见函数

  • 数学函数:
    round(x,y) x为数值,y为小数点后保留多少位

  • 字符串函数:
    concat(s1,s2,…)将s1和s2字符串合并
    replace(s,s1,s2)将字符串s中的s1字符串替换为s2字符串
    left(s,n)从左侧截取n个字符串
    right(s,n)从右侧截取n个字符串
    substring(s,n,m)从n开始,返回包含n的m个值(字符串首个字符的索引从1开始;或者倒数第一个字符索引为-1)
    substring_index(str,delim,count):str为要处理的字符串,delim为分隔符;count计数;count为指定某一个之前的字符串

    如 str=www.wiki.com
    则 substring_index(str,‘.’,1) 处理的结果是:www
    substring_index(str,‘.’,2) 得到的结果是:www.wiki
    substring_index(str,‘.’,-2) 得到的结果为:wikibt.com

  • 数据类型转换函数:
    cast(x as type) 将x转换为type类型,type可以为char(n)、date、time等

  • 日期函数
    year(date)、month(date)、day(date):从date中分别截取年月日
    date_add(‘2021-08-03 23:59:59’,interval 1 second)对时间进行加法操作
    date_sub(date,interval expr type)对时间进行减法操作,type可以为second、minute、hour、day、month、year
    datediff(date1,date2)计算两个日期的相隔天数
    date_format(date,format)将日期和时间格式化,format为%Y,%D

  • 条件判断函数
    if (1<2,‘True’,‘False’),if(expr,v1,v2)表达式为真返回v1,表达式为假返回v2

    case expr when v1 then r1 when v2 then r2 else rn end
    当expr=v1时,返回r1,当expr=v2时,返回值r2,当两者都不是时,返回值rn,结束;
    case 2 when 1 then “one” when 2 then “two” else “more” end

    case when v1 then r1 [when v2 then r2] [else rn] end
    case when 1<0 then ‘T’ else ‘F’ end
    判断1<0,如果为真,返回T,如果为假,返回F

窗口函数

  1. 语法:
  • rank() over(partition by 字段名1 order by 字段名2 desc/asc)as pron
  • 按照字段名1进行分区;在每一个分区内部按照字段名2进行降序/升序;之后为分区内排序后的记录添加次序并命名为pron
  1. 专用窗口函数:rank()、dense_rank()、row_number()

    • rank():跳跃式排序,
      99、99、90、89排序结果为1,1,3,4
    • dense_rank():并列连续排序,
      99、99、90、89排序结果为1,1,2,3
    • row_number():连续性排序,
      99、99、90、89排序结果为1,2,3,4
  2. 偏移分析窗口函数:lag()、lead()

    • lag():向上取数据。

        confirmed-lag(confirmed,1) over(partition by name order by date desc) 
        按照国家(name)进行分区,再对分区内按照日期(date)降序排序,然后取前一天确诊人数(lag......),当日的确诊人数(confirmed)与前一天确诊人数相减,得到新增人数
      
    • lead():向下取数据

  3. 注意

    • 窗口函数只能用在select语句中
    • partition by可以没有,就是对整个表格进行order by排序;
    • 窗口函数over中的order by子句不会影响最终结果的排序,只能用来决定窗口函数按照何种顺序排序
  4. 聚合函数在窗口函数的应用:计算的是累积到当前行的所有的数据的聚合

     sum(sale_price) over(order by product_id) as current_sum
     1. 按照product_id升序排序,之后计算sale_price的和,命名为current_sum
     2. 假如按照product_id排序后,sale_price值的顺序为1000、500、4000、3000,那么,SQL语句的执行结果为1000,100+500,1000+500+4000;1000+500+4000+3000
     3. avg()计算当前所在行及之前所有行的均值
    
  5. 计算移动平均

    rows 2 preceding

    • preceding 截止到之前n行,加上自身行
    • following 截止到之后n行,加上自身行
    • between 1 preceding and 1 following “之前1行”+“之后1行”+“自身”

    avg(sale_price) over(order by product_id rows 2 preceding) as moving_avg

    1. 按照product_id排序后,sale_price值的顺序为1000,500,4000,3000,6800
    2. 计算当前行和之前2行的平均值,结果为(1000)/1,(1000+500)/2,(1000+500+4000)/3,(500+4000+3000)/3,(4000+3000+6800)/3

    avg(sale_price) over(order by product_id rows between 1 preceding and 1 following) as moving_avg

    1. 按照product_id排序后,sale_price值的顺序为1000,500,4000,3000
    2. 计算当前行、之前1行和之后1行的平均值,结果为(1000+500)/2,(1000+500+4000)/3,(500+4000+3000)/3,(4000+3000+6800)/3
  6. partition by h和group by能同时存在吗?
    group by 字段1,字段2与group by 字段2,字段1运行出的结果为什么不一样

  7. 窗口函数:只能用在select语句中

  8. 偏移分析窗口函数

  • lag()向上取数据
    lag(字段名1,num) over(partition by 字段名2 order by 字段名3 desc/asc)
    根据字段名2进行分区;分区内按照字段名3进行排序;然后取当前行的上num行的字段名1的值

    字段名1-lag(字段名1,num) over(partition by 字段名2 order by 字段名3)
    confirmed-lag(confirmed,1) over(partition by name order by date desc)
    按照国家(name)进行分区,再对分区内按照日期(date)降序排序,然后取前一天确诊人数(confirmed);当日的确诊人数(confirmed)与前一天确诊人数相减,得到新增人数

    • lead()向下取数据

10.计算移动平均
preceding
weekday(date)取星期,返回值为0-6,对应星期一到星期日
dayofweek(date)取星期,返回值为1-7s,对应星期一到星期日
经典题目:

select name,date_format(whn,'%Y-%m-%d'),confirmed-lag(confirmed,1) over(order by whn)
from covid
where name='Italy' and weekday(whn)=0
order by whn desc;

以上是关于0. SQL细节要点的主要内容,如果未能解决你的问题,请参考以下文章

2023-01-11:体育馆的人流量。编写一个 SQL 查询以找出每行的人数大于或等于 100 且 id 连续的三行或更多行记录。返回按 visit_date 升序排列 的结果表。 DROP TAB

SQL 习题2

DQL查询语句

[算法分析]二分查找细节分析与技术要点

cgb2109-day04

sql server查询问题。