sql----连续性问题终极万能模板(2021-07-08)

CODE君这几天遇到个烦人的问题,连续性问题!!在这里看到别人的帖子备受触动,写一篇文章分享给大家,一定要收藏好,面试必备,个人能力的体现~~~~~~~~

有一张“用户登陆记录表”,包含两个字段:用户id、日期。

在这里插入图片描述

【问题】查询2021年每个月,每个用户连续登陆的最多天数。

【解题步骤】

  1. 连续问题的万能模板
1 select distinct1
2 from (
3 select1,
4 lead(1,1) over(order by 序号) as2,
5 lead(1,2) over(order by 序号) as3,
6 ...
7 lead(1,n-1) over(order by) as 列n,
8 from 表名
9 ) as a
10 where (a.1 = a.2 and ... and a.1 = a.列n);
  1. 窗口函数

窗口函数lead使用方法:

1 lead/lag(字段名,N,默认值) over(partion by …order by …)
默认值是指:当向上N行或者向下N行值时,如果已经超出了表行和列的范围时,会将这个默认值作为函数的返回值,若没有指定默认值,则返回Null。

窗口函数lead可以获取每个字段的后面的第n个值,并生成新的一列。

而这道题描述的“用户连续登陆”中的“连续”可以理解为用户当前的登陆日期与本月下一次登陆日期相差一天。

我们可以先用窗口函数lead获取“用户当月下一个登陆日期”:

1 select 用户id,
2        month(日期) as,
3        日期,
4        lead(日期,1,'当月最后登陆日期') over(partition by month(日期), 用户id order by 日期) as 用户当月下一个登陆日期
5 from 用户登陆记录表;

在这里插入图片描述

当“日期”是该用户在当月最后一天登陆时,记录为“当月最后登陆日期”,如果不进行设置,将会返回Null,不利于理解。

从结果看,我们可以获得以下信息:

1)当“日期”与“用户当月下一个登陆日期”只相差一天,即用户本次登陆为连续登陆;

2)当“日期”与“用户当月下一个登陆日期”相差大于一天,即用户本次登陆为连续登陆的最后一天(也有可能仅登陆一天);

3)当“用户当月下一个登陆日期”等于“当月最后登陆日期”,即用户本次登陆为本月最后一天登陆。

这样,可以判断用户连续登陆的情况。

接下来就解决用户每次连续登陆天数的计算。

  1. 子查询

在这里插入图片描述

用户每次连续登陆天数与用户登陆顺序存在某种必然的关系,此时我们可以先用子查询将用户在本月的阅读顺序查询出来,使用窗口函数row_number:

 
1 select *,
2        lead(日期,1,'当月最后登陆日期') over(partition by, 用户id order by 每个月登陆顺序) as 用户当月下一个登陆日期
3 from (
4 select 用户id,
5        month(日期) as,
6        日期,
7        row_number() over (partition by month(日期), 用户id order by 日期) as 每个月登陆顺序
8 from 用户登陆记录表
9 ) as t1;

在这里插入图片描述

可以看出,当连续终止时,即:

1)“日期”与“用户当月下一个登陆日期”相差大于一天;

2)“用户当月下一个登陆日期”等于“当月最后登陆日期”;

两种情况。

将这两种情况过滤出来之后,用户连续登陆天数为:当前登陆顺序减去上一个登陆顺序。

1 select *,
2        lag(每个月登陆顺序,1) over(partition by, 用户id order by 每个月登陆顺序) as 上一个登陆顺序
3 from (
4 select *,
5        lead(日期,1,'当月最后登陆日期') over(partition by, 用户id order by 每个月登陆顺序) as 用户当月下一个登陆日期
6 from (
7 select 用户id,
8        month(日期) as,
9        日期,
10        row_number() over (partition by month(日期), 用户id order by 日期) as 每个月登陆顺序
11 from 用户登陆记录表
12 ) as t1
13 ) as t2
14  where date_sub(用户当月下一个登陆日期,interval 1 day) <> 日期 or 用户当月下一个登陆日期 = '当月最后登陆日期';

在这里插入图片描述

“上一个登陆顺序”为Null时,用0代替(使用coalesce函数),那么“每个月登陆顺序”减去“上一个登陆顺序”就是本次连续登陆天数。

【重点】:这里介绍一下coalesce函数,我也是第一次接触,很神奇!
在这里插入图片描述

具体怎么用呢?

上面的函数说明通俗来说coalesce()的作用是:返回传入的参数中第一个非null的值。expre1不为空值则返回expre1;否则判断expre2是否是空值,如果expre2不为空值则返回expre2;否则判断expre3是否是空值,如果expre3不为空值则返回expre3;……以此类推,如果所有的表达式都为空值,则返回NULL。

为简单起见,举例如下:

1、 input:select coalesce(NULL,NULL,1)

    output:1

2、 如果传入的参数所有都是NULL,则返回NULL,比如
input:select coalesce(NULL,NULL,NULL,NULL,NULL)
output:NULL

3、 最常用的一种用法是假设某个字段除了有实例的记录之外都是默认值NULL,但后续计算需要用到这个字段,如果为NULL的话无法计算或展示,现在想将该字段中的NULL值全部替换成0,则可以使用coalesce()函数。以下的sql能够很好的展示其具体是怎么进行操作的:

CREATE TABLE
IF NOT EXISTS test (
    id INT (11) PRIMARY KEY auto_increment COMMENT '主键id',
    score INT (11) COMMENT '分数',
    score_avg INT (11) COMMENT '平均分数'
);

INSERT INTO test(id, score,score_avg)
VALUES
    (1, 90, 80),
    (2, 56, 80),
    (3, NULL, 80),
    (4, 69, 80),
    (5, 89, 80),
    (6, 99, 80),
    (7, 100, 80),
    (8, NULL, 80),
    (9, 47, 80),
    (10, NULL, 80),
    (11, NULL, 80),
    (12, 78, 80);

以上是建表语句以及插入数据的Mysql语句。现在要将score中的NULL值替换成0。

select id,score,coalesce(score, 0) as score_act from test;

在这里插入图片描述

从以上结果清楚的看出,coalesce(score, 0) as score_act新的一列当score不是NULL值时取原值,当score是NULL值时取0。

4、在例子3的基础上再举一个例子。

update test set score_avg = NULL where id = 3;

则原始数据如下所示:

在这里插入图片描述

select id, score, score_avg, coalesce(score, score_avg, 0) as score_act from test;
结果如下:

在这里插入图片描述

可以看出,coalesce(score,score_avg,0) as score_act表示:

当score = 非空值时,score_act = score 例如id = 1、4

当score = NULL值时,看score_avg的值,若score_avg = 非空值,score_act = score_avg 例如id = 8、10、11

  1. 汇总分析

最后获取“每个月,每个用户连续登陆的最多天数”,使用group by函数。

1 select,
2        用户id,
3        max(连续登陆天数) as 连续登陆的最多天数
4 from (
5 select *,
6        每个月登陆顺序 - coalesce(lag(每个月登陆顺序,1) over(partition by, 用户id order by 每个月登陆顺序),0) as 连续登陆天数
7 from (
8 select *,
9        lead(日期,1,'当月最后登陆日期') over(partition by, 用户id order by 每个月登陆顺序) as 用户当月下一个登陆日期
10 from (
11 select 用户id,
12        month(日期) as,
13        日期,
14        row_number() over (partition by month(日期), 用户id order by 日期) as 每个月登陆顺序
15 from 用户登陆记录表
16 ) as t1
17 ) as t2
18 where date_sub(用户当月下一个登陆日期,interval 1 day) <> 日期 or 用户当月下一个登陆日期 = '当月最后登陆日期'
19 ) as t3
20 group by,用户id;

在这里插入图片描述

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
达梦数据库_SQL语言手册.pdf 数据库快照定义语句 数据库快照删除语句 第章数据查询语句和全文检索语句 单表查询 简单查询 带条件查询 集函数 情况表达式 连接查询 子查询 标量子查询 表子查询 派生表子查询 定量比较 带 谓词的子查询 多列表子查询 查询结果的合并 和 子句的使用 子句的使用 子句 选取前儿条数据 选取其屮几条数据 全文检索 层次查询 层次查询子句 层次查询相关伪列 层次查询相关操作符 层次查询相关函数 查看执行计划 第章数据的插入、删除和修改 数据插入语句 数据修改语句 数据删除语句 伪列的使用 和 自增列的使用 自增列定义 属性 第章视图 视图的作用 视图的定义 视图的删除 视图的查询 视图数据的更新 第章嵌入式 前缀和终结符 宿主变量 输入和输出变量 指示符变量 服务器登录与退出 登录服务器 退出服务器 游标的定义与操纵 定义游标语句 打开游标语句 拨动游标语句 关闭游标语句 关于可更新游标 游标定位删除语句 游标定位修改语句 单元组查询语句 动态 立即执行语句 准备语句 执行语句 异常处理 第章函数 数值函数 字符串函数 日期时间函数 空值判断函数 类型转换函数 杂类函数 系统函数 存储加密函数 标记处理函数 备份恢复函数 附加分离数据库 第章一致性和并发性 事务相关语句 事务的开始 事务的结束 保存点相关语句 设置事务隔离级及读写特性 手动上锁语句 第章存储模块 存储模块的定义 存储模块的删除 存储模块的控制语句 语句块 赋值语句 条件语句 循环语句 语句 调用语句 语句 语句 语句 语句 打印语句 存储模块的异常处理 异常变量的说明 异常的抛出 异常处理器 异常处理用法举例 存储模块的语句 游标 动态 游标变量 返回查询结果集 语句应用举例 客户端存储模块 子过程、子函数 子过程 子函数 记录类型 记录类型定义 记录赋值 第章触发器 触发器的定义 触发器类型 触发器激发顺序 新、旧行值的引用 触发器谓词 变异表 设计触发器的原则 触发器的删除 禁止和允许触发器 触发器应用举例 使用触发器实现审计功能 使用触发器维护数据完整性 使用触发器保障数据安全性 使用触发器派生字段值 第章安全管理 创建角色语句 删除角色语句 授权语句数据库权限 授权语句对象权限 授权语句角色权限 回收权限语句数据库权限 回收权限语句对象权限 回收权限语句角色权限 策略与标记管理 创建策略 修改策略 删除策略 安全标记 用户标记设置语句 表标记设置语句 审计设置语句 审计取消语句 审计信息查阅语句 审计分析 创建审计分析规则 删除审计分析规则 加密引擎 创建加密引擎 修改加密引擎 删除加密引擎 第章外部链接 创建外部链接 删除外部链接 使用外部连接进行远程对象操作 第章备份还原 备份数据库 还原数据库 第章包 创建包 创建包规范 创建包主体 删除包 删除包规范 删除包主体 应用实例 第章同义词 创建同义词 删除同义词 附录关键字和保留字 附录 语法描述说明 附录命令参考 附录系统存储过程和函数 附录技术支持 第1章结构化查询语言简介 第章结构化查询语言 简介 结构化查询语言 是在年提出的一种关系数据库语言。 由于语言接近英语的语句结构,方便简洁、使用灵活、功能强人,倍受用户及计算机工业 界的欢迎,被众多计算机公司和数据库厂商所采用,经各公司的不断修改、扩充和完善,语 言最终发展成为关系数据库的标准语言。 的第一个标准是年月由美国国家标准化组织公布的 数据库语言 简称 年国际标准化组织也通过了这一标准。以后通过对 的不断修改和完善,于年第二次公布了标准 年又公布了标准 即 。最新的标准是 (也称 年作为 《信息技术——数据库语言》发布。我国也相继 公布了数据库语言的国家标准。 成为国际标准以后,其影响远远超出了薮据库领域。例如在 软件工程、人工智 能、分布式等领域,人们不仅把作为检索数据的语言规范,而且也把作为检索图形、 图象、声音、文字等信息类型的语言规范。目前,世界上大型的著名数据库管理系统均支持 语言,如 等。在未来相当长的时间里,仍将是数据库领 域以至信息领域中数据处理的主流语言之 由于不同的产品,大都按自己产品的特点对语言进行了扩充,很难完全符合 标准。目前在 市场上已将的符合夲作为衡量产品质量的重要指标,并研制成专门的 测试软件,如 目前, 入门级和过渡级的符合均达到,并且部分支持 更新的 标准。同时还兼容 和 的部分语言特性。本章主要 介绍系统所支持的语言 语 语言的特点 语言符合结构化査询语言标准,是标准的扩充。它集数据定乂、数据査 询、薮据操纵和数据控制于一体,是一种统一的、综合的关系数据库语言。它功能强大,使用简 单方便、容易为用户掌握 语言具有如下特点: 功能一体化 的功能一体化表现在以下两个方面 支持多媒体数据类型,用户在建表时可直接使用。系统在处理常规数据与 多媒体数据时达到了四个一体化:一体化定义、一体化存储、一体化检索、一体化处理,最大限 度地提高了数据库管理系统处理多媒体的能力和速度; 语言集数据库的定义、査询、更新、控制、维护、恢复、安全等一系列操作于 体,每一项操作都只需一种操作符表示,格式规范,风格一致,简单方便,很容易为用户所掌 握 两种用户接口使用统一语法结构的语言 语言既是自含式语言,又是嵌入式语言。作为自含式语言,它能独立运行于联机交 互方式。作为嵌入式语言, 浯句能够嵌入到和语言程序中,将高级语言也称主 语言灵活的表达能力、强大的计算功能与 语言的数据处理功能相结合,完成各种复杂 的事务处理。而在这两种不同的使用方式中, 语言的语法结构是一致的,从而为用户使 第1章结构化查询语言简介 用提供了极大的方使性和灵活性。 高度非过程化 语言是·种非过程化语言。用户只需指出“做什么”,而不需指出“怎么做”,对数 据存取路径的选择以及 语句功能的实现均由系统自动完成,与用户编制的应用程序与 具体的机器及关系 的实现细节无关,从而方便了用户,提高了应用程序的开发效,也 增强了数据独立性和应用系统的叮移植性。 面向集合的操作方式 语言采用了集合操作方式。不仅查询结果可以是元组的集合,而且一次插入、删除、 修改操作的对象也可以是元组的集合,相对于面向记录的数据库语言一次只能操作一条记录来 语言的使用简化了用户的处理,提高了应用程序的运行效 语言简洁,方便易学 语言功能强大,格式规范,表达简洁,接近英语的语法结构,容易为用户所掌握。 保留字与标识符 标识符的语法规则兼容标准 ,标识符分为正规标识符和定界标识符两大类。 正规标识符以字母、、、或汉字开头,后面可以跟随字母、数字、、、或者汉字,正 规标识符的最大长度是个英文字符或个汉字。正规标识符不能是保留字 正规标识符的例子:, 表 定界标识符的标识符体用双引号括起来时,标识符体可以包含任意字符,特别地,其中使用 连续两个双引号转义为一个双引号 定界标识符的例子: 保留字的清单参见附录 语言的功能及语句 语言是一种介于关系代数与关系演算之间的语言,其功能主要包括数据定义、查询 操纵和控制四个方面,通过各种不同的语句米实现。按照所实现的功能, 语句分 为以下几种 数据库、登录、用户、模式、基表、视图、索引、序列、全文索引、存储过程和触发器 的定义和删除语句,登录、基表、视图、仝文索引的修改语句,对象的更名语句; 査询(含全文检索)、插入、删除、修改语句; 数据库安全语句。包括创建角色语句、删除角色语句,授权语句、回收权限语句,修改 登录口令语句,审计设置语句、取消审计设置语句等。 在嵌入方式中,为了协调 语言与主语言不同的数据处理方式 语言引入 了游标的概念。因此在嵌入方式下,除了数据查询语句一次查询一条记录外,还有几种与游标 有关的语句: 游标的定义、打廾、关闭、拨动语句 游标定位方式的数据修改与删除语句。 为了有效维护数据库的完整性和一致性,支持 的并发控制机制 语言提供 了事务的回滚( )与提交( )语句。同时允许选择实施事务级读一致 性,它保证同一事务内的可重复读,为此提供用户多种手动上锁语句,和设置事务隔离级别 第1章结构化查询语言简介 语句 所支持的数据类型 数据类型是可表示值的集。值的逻辑表示是字值。值的物理表示依赖于实现。系统具 有 的绝大部分数据类型,以及部分 和 的数据类型。 常规数据类型 字符数据类型 类型 语法:长度 功能: 数据类型指定定长字符串。在基表中,定义 类型的列时,可以指 定一个不超过的正整数作为字符长度,例如 如果未指定长度,缺省为。 确保存储在该列的所有值都具有这一长度。 数据类型的最大长度由数据库页面大 小决定,字符类型最大长度和页面大小的对应关系请见下表支持按字节存放字符 串 表 数据库页面大 最大长度 类型 语法: 长度 功能:与 相同。 类型 语法: 长度 功能 数据类型指定变长字符串,用法类似 数据类型,可以指定一 个不超过的正整数作为字符长度,例如: 。如果未指定长度,缺省为 在系统中, 数据类型的实际最大长度由数据库页面大小决定,具体最 大长度算法如表 的区别在于前者长度不足时,系统自动填充空 格,而后者只占用实际的字节空间。 表 数据库页面大 实际最大长度 注:这个限制长度只针对建表的情况,在定义变量的时候,可以不受这个限制长度的限 制 数值数据类型
先登陆服务器: telnet 192.168.0.23 公帐号: openlab-open123 tarena-tarena 再进入SQLsqlplus sd0807/sd0807 帐号:sd0807-密码同样 公帐号:openlab-open123 设置环境变量: ORACLE_SID=oral10g\ --变局部变量 export ORACLE_SID --变全局变量 unset ORACLE_SID --卸载环境变量 ORACLE_HOME=... --安装路径;直接用一句语句也可以,如下 export ORACLE_HOME=/oracledata/.../bin: 一、注意事项: 大小写不敏感,即不区分大小写。提倡关键字大写,便于阅读和调式。 “!”在SQL环境下执行Unix命令。 SQL语句是由简单的英语单词构成;这些英语单词称为关键字/保留字,不做它用。SQL由多个关键字构成。 SQL语句由子句构成,有些子句是必须的,有些是可选的。 在处理SQL语句时,其中所有的空格都被忽略(空格只用来分开单词,连续多个空格当一个用)。 SQL语句可以在一行上写出,建议多行写出,便于阅读和调试。 多条SQL语句必须以分号分隔。多数DBMS不需要在单条SQL语句后加分号,但特定的DBMS可能必须在单条SQL语句后加分号。 SQL语句的最后一句要以 “;”号结束 二、写子句顺序 Select column,group_function From table [Where condition] [Group by group_by_expression] [Having group_condition] …… [Order by column]; --最后 三、常用简单语句: clear screen:清屏 edit:编辑刚才的一句。 desc/describe:(列出所有列名称) 用法: DESCRIBE [schema.]object[@db_link] dual:亚表,临时用。如:desc dual;/from dual; rollback:回溯,回溯到上次操作前的状态,把这次事务操作作废,只有一次(DDL和DCL语句会自动提交,不能回溯)。 可以用commit语句提交,这样就回溯不回了。 set pause on\off :设置分屏(设置不分屏) set pause "please put an enter key" 且 set pause on:设置带有提示的分屏 oerr ora 904 :查看错误 set head off :去掉表头 set feed off :去掉表尾 保存在oracle数据库中的所有操作细节: spool oracleday01.txt :开始记录 spool off :开始保存细节 四、SELECT语句:选择操作、投影操作。 select:从一个或多个表中检索一个或多个数据列。包含信息:想选择什么表,从什么地方选择。必须要有From子句。(最常用) 当从多张表里查询的时候,会产生笛卡尔积;可用条件过滤它。 当两个表有相同字段时必须加前缀,列名前需加表名和“.”,如“s_emp.id”。 1、用法:SELECT columns,prod2,prod3<列> FROM Table1,table2<表名> 分号结束 如: select id from s_emp; select last_name,name from s_emp,s_dept where s_emp.dept_id=s_dept.id;--列表每人所在部门 SELECT * FROM Products; --检索所有列。 数据太多时,最好别使用上句,会使DBMS降低检索和应用程序的性能。(*通配符) 2、对数据类型的列可进行运算(如加减乘除)。 3、对列起别名:有直接起别名,加AS起别名,用双引号起别名等三种方法 (单引号,引起字符串;双引号,引起别名。起别名有符号,或者区分大小写时,必须用双引号) 多表查询时,可给表起别名。(给列起别名,列<空格>列别名;给表起别名,表<空格>表别名;)。 如:Select first_name EMPLOYEES, 12*(salary+100) AS MONEY, manager_id "ID1" From s_emp E; 4、字段的拼接,可用双竖线(双竖线只能用于select语句里)。不同的DBMS可能使用不同的操作符;拼接的字段同样可以起别名。 如:Select first_name ||' '|| last_name || ', '|| title "Employees" From s_emp; 排他锁:Select id,salary From s_emp where id=1 For Update; 可以阻止他人并发的修改,直到你解锁。 如果已有锁则自动退出:Select id,salary From s_emp where id=1 For Update NoWait; FOR UPDATE :可以再加 OF 精确到某格。如: ... For Update OF salary ... 注意要解锁。 五、ORDER BY 子句,排序 Order by:按某排序列表(默认升序 asc,由低到高;可加 desc,改成降序由高到低) 检索返回数据的顺序没有特殊意义,为了明确地排序用 SELECT 语句检索出的数据,可使用 ORDER BY 子句。 ORDER BY 子句取一个或多个列的名字。 对空值,按无穷大处理(升序中,空值排最后;降序中排最前)。 1、用法:Select prod_id,prod_price,prod_name From Products Order By prod_price,prod_name; (从左到右执行排序,先排price) ORDER BY子句中使用的列将是为显示所选择的列,但是实际上并不一定要这样,用非检索的列排序数据是完全合法的。 为了按多个列排序,列名之间用逗号分开。 2、支持按相对列位置进行排序。 输入 SELECT prod_id,prod_price,prod_name FROM Products ORDER BY 2,3 --(2指price,3指name) 3、升序、降序。默认是升序(asc,从小到大排序),想降序时用desc。 如:SELECT prod_id,prod_price,prod_name FROM Products ORDER BY prod_price DESC; 注意:DESC 关键字只应用到直接位于其前面的列名。如果想在多个列上进行排序,必须对每个列指定DESC关键字。 升序是默认的,可不写,但降序必须写。 六、WHERE子句,选择、过滤 其后只能跟逻辑语句,返回值只有ture或false 如: select last_name,salary from s_emp where salary=1000;--找出工资1000的人 WHERE子句操作符: 1、逻辑比较运算符 = 等于 != 不等于,还有(<> ^= 这两个同样表示不等于) > 大于 >= 大于等于 < 小于 <= 小于等于 2、SQL 比较运算符 between…and… :在两者之间。(BETWEEN 小值 AND 大值) 如:select last_name,salary from s_emp where salary between 1000 and 1500; --工资1000到1500的人,包括1000和1500。 in(列表):在列表里面的。 如:select last_name,dept_id from s_emp where dept_id in(41,42);第41、42部门的人 like : 包含某内容的。模糊查询 可以利用通配符创建比较特定数据的搜索模式,通配符只能用于文本,非文本数据类型不能使用通配符。 通配符在搜索模式中任意位置使用,并且可以使用多个通配符。 通配符%表示任何字符出现任意次数;还能代表搜索模式中给定位置的0个或多个字符。下划线匹配单个任意字符。 如:select table_name from user_tables where table_name like 'S\_%' escape'\'; ' 找出“S_“开头的,由于下划线有任意字符的含义,故需另外定义转移符。 但习惯用“\”,为方便其他程序员阅读和检测,一般不改用其他的。 like 'M%':M开头的 like '_a%':第二个字符是a的 like '%a%'所有含a的 (“_”表示一个任意字符;“%”表示任意多个任意字符。) 单引号里面的内容,大小写敏感。单引号用来限定字符串, 如果将值与串类型的列进行比较,则需要限定引号;用来与数值列进行比较时,不用引号。 is null:是空。(NULL表示不包含值。与空格、0是不同的。) 如:SELECT prod_name,prod_price FROM Products WHERE prod_price IS NULL; 七、高级检索(逻辑运算符): 通常我们需要根据多个条件检索数据。可以使用AND或OR、NOT等连接相关的条件 计算次序可以通过圆括号()来明确地分组。不要过分依赖默认计算次序,使用圆括号()没有坏处,它能消除二义性。 and:条件与 如 SELECT prod_id,prod_price,prod_name FROM Products WHERE prod_price<4 AND vend_id=‘DELL’ or:条件或 (注: and 的优先级比 or 更高,改变优先级可用括号) 如 SELECT prod_id,prod_price,prod_name FROM Products WHERE prod_price<4 OR vend_id=‘DELL’ not:条件非。否定它之后所跟的任何条件 否定的SQL 比较运算符: NOT BETWEEN; NOT IN; NOT LIKE; IS NOT NULL: (注意,按英语习惯用 is not,而不是 not is) NOT 与 IN 在一起使用时,NOT 是找出与条件列表不匹配的行。 IN 列表里有 NULL 时不处理,不影响结果;用 NOT IN 时,有 NULL 则出错,必须排除空值再运算。 in :选择列表的条件 使用IN操作符的优点: 在长的选项清单时,语法直观; 计算的次序容易管理; 比 OR 操作符清单执行更快;最大优点是可以包含其他 SELECT 语句,使用能够动态地建立 WHERE 子句。 如 SELECT prod_id,prod_price,prod_name FROM Products WHERE vend_id IN(‘DELL’,’RBER’,’TTSR’); 八、单行函数: 函数一般在数据上执行,它给数据的转换和处理提供了方便。不同的DBMS提供的函数不同。 函数可能会带来系统的不可移植性(可移植性:所编写的代码可以在多个系统上运行)。 加入注释是一个使用函数的好习惯。 大多数SQL实现支持以下类型的函数: 文本处理, 算术运算, 日期和时间, 数值处理。 Null:空值 空值当成无穷大处理,所有空值参与的运算皆为空。 空值与空值并不相等,因为空值不能直接运算。 如:prod_price="" 这种写法是错的(不要受到corejava的影响) prod_price=NULL 这种写法是错的(不要受到corejava的影响) prod_price IS NULL 这种写法才是对的 NVL:处理空值,把空值转化为指定值。可转化为日期、字符、数值等三种(注意:转化时,两参数必须要同类型) 如:NVL(date, '01-JAN-95') NVL(title,'NO Title Yet') NVL(salary,0) 错误写法: Select last_name,title,salary*commission_pct/100 COMM From s_emp;--没提成的人没法显示工资 正确写法: Select last_name,title,salary*NVL(commission_pct,0)/100 COMM From s_emp;--把提成是空值的转化为0 DISTINCT:过滤重复 把重复的行过滤掉;多个字段组合时,只排除组合重复的。 DISTINCT必须使用列名,不能使用计算或者表达式。 所有的聚合函数都可以使用。如果指定列名,则DISTINCT只能用于COUNT(列名),DISTINCT不能用于COUNT(*)。 如:Select Distinct name From s_dept; Select Distinct dept_id,title From s_emp; 文本处理: TRIM()/LTRIM()/RTIRM():去空格。只能去掉头和尾的空格,中间的不理。 trim(' heo Are fdou ') --> heo Are fdou 输入:select trim(' heo Are fdou ') from dual; -->:heo Are fdou LOWER:转小写 lower('SQL Course') --> sql course UPPER:转大写 upper(' SQL Course') --->SQL COURSE INITCAP:首字母转大写,其余转小写 initcap(SQL Course') '--> Sql Course CONCAT:合成。双竖线只能在select语句里面用,这个可用于任何语句。 Concat('Good','String') --> GoodString SUBSTR:截取。 Substr('String', 1 ,3) --> Str 第一个数字“1”,表示从第几个开始截取;若要从倒数第几个开始,用负数,如“-2”表示倒数第2个。 上式中第2个数字“3”表示截取多少个。 LENGTH:统计长度。 Length('String') --> 6 NVL:转换空值 日期和时间处理: Oracle日期格式:DD-MMM-YYYY (D代表日期date,M代表月month,Y代表年year) 如:SELECT prod_name (DAY表示完整的星期几,DY显示星期的前三个字母) FROM Products WHERE prod_time BETWEEN to_date(’01-JAN-2008’) AND to_date(’31-DEC-2008’); 日期可以进行加减,默认单位是1天。日期与日期可以相减,得出天数;日期与日期但不能相加。 sysdate -> 系统的当天 Months_Between('01-Sep-95','11-Jan-94') --> 19.774194 相差多少个月,Between里面也可以填函数。 Add_months('11-Jan-94',6) --> 11-Jul-94 增加多少个月 Next_day('01-Sep-95','Friday') --> '08-Sep-95' 下一个星期五。其中的'Friday'可用6替代,因为星期日=1 Last_day('01-Sep-95') --> '30-Sep-95' 这个月的最后一天 数值处理:可以运用于代数,三角,几何 ROUND:四舍五入 Round(45.925,2) -> 45.93 Round(45.925,0) -> 46 Round(45.925,-1) -> 50 逗号前一个数是要处理的数据源,后一个参数表示保留多少位小数。 后一参数是负数时,表示舍去小数点前的几位,例3是舍去个位及其后的。不写后一参数时,默认不保留小数。 TRUNC:舍去末位。直接舍去,不会进位。 Trung(45.925,2) -> 45.92 Trung(45.925,2) -> 45.92 Trung(45.925,2) -> 45.92 日期的舍取: 常用的数值处理函数有: ABS() 绝对值 ABS(-5741.5854) --> 5741.5854 PI() 圆周 注意:oracle中不支持 PI()函数;MYSql 支持PI()函数。 SIN() 正统值 Oracle还支持COS()、ASIN()、ACOS()函数 SQRT() 平方根 转化: TO_CHAR(number,'fmt'):把数值转换成字符串 显示数字的命令 9:正常显示数字; 0:显示包括0的数值形式,空位强制补0; $:以美元符号显示货币; L:按当前环境显示相关的货币符号; . 和,:在固定位置出现“.”点 和“,”逗号;不够位时,四舍五入。 例题:SQL> select 'Order'||To_char(id)|| 2 'was filled for a total of' 3 ||To_char(total,'fm$9,999,999') 4 from s_ord 5 where ship_date ='21-SEP-92'; TO_NUMBER(char):把字符转换成数字 九、链接 内链接:严格匹配两表的记录。 外链接分左链接和右链接: 会使用一方表中的所有记录去和另一格表中的记录按条件匹配,空值也会匹配,这个表中的所有记录都会显示, 数据库会模拟出记录去和那些不匹配的记录匹配。 左链接 加号在右面 如:有 TABLE1 TABLE2 1的一条记录在2里面没有匹配上,那么1里面的记录保留 2的一条记录在1里面没有匹配上 ,那么2丢弃 右链接正好相反 --例题:哪些人是领导。 select distinct b.id,b.last_name manager from s_emp a,s_emp b where a.manager_id=b.id(+); 左右顺序有区别,这是另外新建一个表,要显示的是第二个表格的内容。 +放在没有匹配行的表一侧,令表格能完整显示出来。 标准写法:内连接用INNER,左连接用LEFT,右连接用RIGHT。 select distinct b.id,b.last_name manager from s_emp a LEFT join s_emp b ON a.manager_id=b.id; 十、组函数: 分组允许将数据分为多个逻辑组,以便能对每个组进行聚集计算。 Group:分组 Group by:分组。(默认按升序对所分的组排序;想要降序要用 order by)可以包括任意数目的列。 如果嵌入了分组,数据将在最后规定的分组上进行汇总。 GROUP BY 子句中列出的每个列都必须是检索列或有效的表达式,但不能是聚集函数。 *如果在SELECT 中使用表达式,则必须在GROUP BY子句中指定相同的表达式,不能使用别名。 除聚合计算语句外,SELECT语句中的每个列都必须在GROUP BY子句中给出。 如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多行NULL,它们将分为一组。 Having:过滤。分组之后,不能再用where,要用having 选择过滤。Having不能单独存在,必须跟在group by后面。 WHERE在数据分组前进行过滤,HAVING在数据分组后过滤。 可以在SQL中同时使用 WHERE和HAVING,先执行WHERE,再执行HAVING。 聚合函数: AVG:平均值 (忽略值为NULL的行,但不能用 AVG(*)) COUNT:计数 (Count(列)不计算空值;但 COUNT(*)表示统计表中所有行数,包含空值) MAX:最大值 (忽略列值为 NULL 的行。但有些DBMS还允许返回文本列中的最大值, 在作用于文本数据时,如果数据按照相应的列排序,则 MAX()返回最后一行。) MIN:最小值 (忽略值为 NULL 的行。不能用 MIN(*)。一般是找出数值或者日期值的最小值。 但有些DBMS还允许返回文本列中的最小值,这时返回文本最前一行) SUM:求和 (忽略值为 NULL 的值。SUM 不能作用于字符串类型,而 MAX(),MIN()函数能。也不能 SUM(*)) 子查询:查询语句的嵌套 可以用于任意select 语句里面,但子查询不能出现 order by。 子查询总是从内向外处理。作为子查询的SELECT 语句只能查询单个列,企图检索多个列,将会错误。 如:找出工资最低的人select min(last_name),min(salary) from s_emp; 或者用子查询select last_name,salary from s_emp where salary=(select min(salary) from s_emp); E-R图:属性: E(Entity) -R(Relationship) * (Mandatory marked 强制的) 强制的非空属性 o (Optional marked 可选的) 可选属性(可以有值也可以没有) #* (Primary marked ) 表示此属性唯一且非空 约束:针对表中的字段进行定义的。 PK:primary key (主键约束,PK=UK+NN)保证实体的完整性,保证记录的唯一 主键约束,唯一且非空,并且每一个表中只能有一个主键,有两个字段联合作为主键, 只有两个字段放在一起唯一标识记录,叫做联合主键(Composite Primary Key)。 FK:foreign key (外建约束)保证引用的完整性,外键约束,外键的取值是受另外一张表中的主键或唯一值的约束,不能够取其他值, 只能够引用主键会唯一键的值,被引用的表,叫做parent table(父表),引用方的表叫做child table(子表); child table(子表),要想创建子表,就要先创建父表,后创建子表,记录的插入也是如此,先父表后子表, 删除记录,要先删除子表记录,后删除父表记录, 要修改记录,如果要修改父表的记录要保证没有被子表引用。要删表时,要先删子表,后删除父表。 U:unique key(唯一键 UK),值为唯一,不能重复。 在有唯一性约束的列,可以有多个空值,因为空值不相等。 NN:NOT NULL,不能为空。 index(索引)是数据库特有的一类对象,实际应用中一定要考虑索引,view(示图) 数量关系: 一对一关系 多对一关系 一对多关系 多对多关系 范式: 好处:降低数据冗余;减少完整性问题;标识实体,关系和表 第一范式(First normal form:1Nf),每一个属性说一件事情。所有的属性都必须是单值,也就是属性只表示单一的意义。 (记录可以重复,会有大量冗余,没有任何限制) 第二范式(2N范式),最少有一个属性要求唯一且非空PK,其他跟他有关联(记录不可重复,但是数据可能会出现冗余)。 第三范式(3N范式),非主属性只能依赖于主属性,不能依赖于其他非主属性。(解决数据冗余问题,不能存在推理能得出的数据) 一般情况会做到第三范式。 创建表: Create Table 表名 (字段名1 类型(数据长度)(default ...) 约束条件, 字段名2 类型(数据长度) 约束条件 ); 建表的名称: 必须字母开头;最多30字符;只能使用“A~Z、a~z、0~9、_、$、#”; 同一目录下不能有同名的表;表名不能跟关键字、特殊含意字符同样。 如:create table number_1 (n1 number(2,4), n2 number(3,-1), n3 number); create table t_sd0808(id number(12) primary key,name varchar(30) not null); MySQL的: create table student (oid int primary key, ACTNO varchar(20) not null unique, BALANCE double); --MySQL的number类型分小类了,Oracle只有number,且MySQL的数值型不用定大小 Oracle的: create table t_ad (oid number(15) primary key, ACTNO varchar(20) not null unique,BALANCE number(20)); INSERT:插入(或添加)行到数据库表中的关键字。 插入方式有以下几种:插入完整的行;插入行的一部分;插入某些查询的结果。 对于INSERT操作,可能需要客户机/服务器的DBMS中的特定的安全权限。 插入行(方式一) INSERT INTO products VALUES(2008,’TV’,222.22,’US’); 依赖于表中定义的顺序,不提倡使用。有空值时需要自己补上。 插入行(方式二) INSERT INTO products(id,name,price,vend_name) VALUES(2008,’TV’,222.22,’US’); 依赖于逻辑顺序,会自动补上空值,提倡使用。 插入检索出的数据:可以插入多条行到数据库表中 INSERT INTO products(*,*,*,*) SELECT *,*,*,* FROM products_copy; 如果这个表为空,则没有行被插入,不会产生错误,因为操作是合法的。 可以使用WHERE加以行过滤。 复制表: 将一个表的内容复制到一个全新的表(在运行中创建,开始可以不存在) CREATE TABLE 新表名 AS SELECT * FROM 表名; INSERT INTO 与 CREATE TABLE AS SELECT 不同,前者是导入数据,而后者是导入表。 任何SELECT选项和子句都可以使用,包括WHERE和GROUP BY。 可利用联接从多个表插入数据。不管从多少个表中检索数据,数据都只能插入到单个表中。 更新数据 UPDATE 语句 需要提供以下信息:要更新的表;列名和新值;确定要更新的哪些行的过滤条件。 UPDATE 表名 SET vend_name = ‘HP’, prod_name = ‘NEWCOMPUTER’ WHERE vend_name = ‘IBM’; --UPDATE 语句中可以使用子查询,使得能用SELECT语句检索出的数据更新列数据。也可以将一个列值更新为 NULL。 删除数据 DELETE 语句 DELETE FROM products WHERE prod_name = ‘COMPUTER’; 全行删除,不要省略WHERE,注意安全。 DELETE不需要列名或通配符。删除整行而不是删除列。DELETE是删除表的内容而不是删除表。 如果想从表中删除所有内容,可以使用TRUNCATE TABLE语句(清空表格),它更快。 数字字典表: Sequence:排列。存储物理地址 Index:索引。依附于表,为提高检索速度。 View:视图。看到表的一部分数据。 限制数据访问。简化查询。数据独立性。本质上是一个sql查询语句。 Create[or Relace][Force|noForce] View 视图名 [(alias[,alias]…)] 别名列表 As subquery [With Check Option [Constraint ……]] [With Read Only] 注意:有些DBMS不允许分组或排序视图,不能有 Order by 语句。可以有 Select 语句。 删除视图: DROP VIEW 视图名 Rownum:纬列。内存里排序的前N个。 在where语句中,可以用=1,和<=N 或 <N;但不能用=N 或 >N。 因为这是内存读取,没有1就丢弃再新建1。只能从1开始。需要从中间开始时,需二重子rownum语句需取别名。 经典应用: Top-n Analysis (求前N名或最后N名) Select [查询列表], Rownum From (Select [查询列表(要对应)] From 表 Order by Top-N_字段) Where Rownum <= N 分页显示: --取工资第5~10名的员工(二重子rownum语句,取别名) select rn,id,last_name,salary From ( select id,last_name,salary,Rownum rn From (Select id,last_name,salary from s_emp order by salary desc) where rownum <= 10) where rn between 5 and 10; Union:合并表 Select … Union Select… 把两个Select语句的表合并。 要求两表的字段数目和类型按顺序对应。合并后的表,自动过滤重复的行。 Intersect:交。 同上例,把两个Select表相交。 Minus:减。 把相交的内容减去。 not exists 除运算。 添加字段(列): Alter Table 表名 Add (column dataype [Default expr][Not Null] [,column datatype]…); 添加有非空限制的字段时,要加Default语句 字段名字不可以直接改名,需要添加新字段,再复制旧字段后删除旧字段。 添加约束: Alter Table 表名 Add [CONSTRAINT constraint] type (column); 添加非空约束时,要用Modify语句。 查看约束名时,可以违反约束再看出错提示;或者查看约束字典desc user_constraints 减少字段: Alter Table 表名 Drop (column [,column]…); 删除约束: Alter Table 表名 Drop CONSTRAINT column; 或: Alter Table 表名 Drop Primary Key Cascade; 暂时关闭约束,并非删除: Alter Table 表名 Disable CONSTRAINT column Cascade; 打开刚才关闭的约束: Alter Table 表名 Enable CONSTRAINTcolumn; 修改字段: Alter Table 表名 Modify (column dataype [Default expr][Not Null] [,column datatype]…); 修改字段的类型、大小、约束、非空限制、空值转换。 删除表: 会删除表的所有数据,所有索引也会删除,约束条件也删除,不可以roll back恢复。 Drop Table 表名 [Cascade Constraints]; 加 [Cascade Constraints] 把子表的约束条件也删除;但只加 [Cascade]会把子表也删除。 改表名: Rename 原表名 To 新表名; 清空表格: TRUNCATE TABLE 表名; 相比Delete,Truncate Table清空很快,但不可恢复。清空后释放内存。 Delete 删除后可以roll back。清空后不释放内存。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值