6.1 Data Type

查看数据所占空间的两个函数:

-- 查看所占字节数
select length('你好,世界') from dual;
-- 查看所占字符数,即多少个字母,多少个汉字
select lengthb('您好,美女') from dual;-- 比如
create table aaa (a varchar2(6));
insert into aaa values ('aaa');
insert into aaa values ('你好');
select a, length(a), lengthb(a) from aaa;

6.1.1 字符类型

  • char,固定长度,默认1,最大2000,如果长度不够,用空格填充。
  • varchar2 类型,变长字符串,最多4000字节长度。
  • nvarchar2,跟上面比,增加了字符集的支持。
  • long,用于存储大数据,最多 2G。不建议使用,已被 clob 类型替代。
    -- 它的使用跟 SQL 的标准 varchar 基本类似,
    -- 但是,在 Oracle 中请使用 varchar2 而不是 varchar,
    -- varchar2 的效率更高,并且在兼容性上做的更好
    -- 初始化的语句为: name varchar2(20)
    -- 其中 20 代表最大长度, 默认单位是字节。
    -- 如果定义为: name varchar2(20 char),表示最大保存20个字符长度的字符串。
    create table aaa (a varchar2(20),        -- 最大是20个字节长度,默认单位字节b varchar2(20 byte),   -- 最大为20个字节长度,跟上面是一样的c varchar2(20 char)    -- 最大为20个字符长度
    );-- varchar2 最大能保存 4000 个字节
    -- 如果是英文,则是 4000 个英文字母
    -- 如果是中文,需要按照字符集判断:
    --   GBK 用两个字节表示一个汉字,所以 varchar2 最多表示 2000 个汉字
    --   UTF-8 是变长字符集,用一个字节表示一个英文字母,用3个或4个字节表示一个汉字,所以,最多可以保持1333个汉字。
    select length('你好') from dual;   -- 2
    select lengthb('你好') from dual;  -- 4-- char 类型是固定长度的,可能会占用更多空间。但是因为长度固定,块的分配管理比较块,效率很高。
    -- varchar2 是变长的,会占用尽量少的空间。但是需要消耗更多资源为分配变长空间,效率略低。
    -- 所以,用哪一种,酌情而定。-- nchar/nvarchar2 是 char/varchar2 的字符集支持版本,对多字节字符有算法上的优化。
    -- 感觉用的比较少。
    

6.1.2 数值类型

  • number,占用 38 位,有自己的内部表示方式,可以表示天文数字。
  • int/float,number 类型的子类型
    -- number 类型的语法为 NUMBER [位数[,小数点数]]
    create table bbb (a number,         -- 一共 38 位,其他按照插入的值自动判断b number(5),      -- 一共5位c number(5, 2),   -- 一共5位,3位整数,2位小数d number (*, 2)   -- 保存两位小数,其他随意e number (*, 0),  -- 相当于 intf int
    );-- 插入的时候,多余的小数会被切掉,但如果整数位超了,会报错
    insert into bbb values (111.223, 111.223, 111.223, 111.223, 22);-- 一般情况下,作为表的主键,设为 int 类型就可以了
    

6.1.3 日期类型

  • date,存储的年月日,时分秒
  • timestamp,存储的更详细,包括时区,还有精确到小数点后6位的秒数等
  • timestamp with time zone,可以设置时区
  • sysdate/systimestamp 连个函数用来查询当前的日期
    -- 显示当前时间
    select sysdate from dual;
    select systimestamp from dual;-- 时间的显示格式,由 nls_date/time_format 等参数控制
    show parameter nls
    -- 如果想格式化时间,可以有下面方法:
    -- 1. 更改注册表中变量
    -- # set NLS_DATE_FORMAT='yyyy.mm.dd'
    -- 2. 更改当前会话中的格式
    alter session set NLS_DATE_FORMAT='yyyy.mm.dd';
    -- 3. 手动转型:to_char
    -------- yyyy 代表四位的年, rr 代表两位的年
    -------- mm 代表两位的数字月,
    -------- dd 代表两位的数字日,
    -------- hh 代表12格式的小时, hh24 代表24格式的小时
    -------- mi 代表分钟数
    -------- ss 代表秒数
    select to_char(sysdate, 'yyyy-mm-dd') from dual;-- date 比 timestamp 占用更少空间
    -- timestamp 比 date 更精确
    -- 没有优劣,使用哪一个,按照需求来-- 插入时间,使用 to_date 转型。
    -- 符合标准日期格式的字符串,可以隐式转型。
    create table stu (name varchar2(20), birth date default sysdate);
    insert into stu values ('aaa', sysdate);      -- 当前时间
    insert into stu values ('bbb', '20100303');   -- 插入成功,char 自动转型为 date
    insert into stu values ('ccc', to_date('1999-01-11', 'yyyy-mm-dd'); -- 手动转型
    

6.1.4 二进制类型

  • RAW
  • LONG RAW

6.1.5 LOB 类型

Large Object,用来存储大数据。

Oracle 提供了 DBMS_LOG 包对 LOB 类型的数据进行处理。 也可以在 jdbc 中通过 getXLob() 的方式进行 lob 字段的处理。

  • CLOB,charactor,存储大容量字符串
  • BLOB,Binary,存储二进制文件,如小图片、小电影
  • BFile/XMLType 等
    create table article
    (id int primary key,title varchar2(20) not null,content clob,createtime date default sysdate
    );
    insert into article (id, title, content) values (1, 'Oracle 使用指南', '你好');
    

6.1.6 伪列(Pseudo Column)

  1. rowid

    rowid 是 oracle 中的伪列。可以通过下面语句显示:

    select d.rowid, d.* from dept d
    

    它是唯一的,不可变的,固定长度的。

    它是数据存储物理地址的一种映射。一共有18位,前6位表示对象id,后3位表示fno,后6位表示块编号,最后3位表示行编号。 所以,通过rowid可以最快速度地定位到数据所在的位置。

    比如,如果某行数据的 rowid 是 AAAO0fAAFAAAAlmAAA, 那么可以根据它直接定位数据的物理地址:

    AAAO0f AAF AAAAlm AAA
    对象号(6个字符) 文件号(3个字符) 块号(6个字符) 行号(3个字符)

    rowid 是 oracle 特有的。

    不建议使用 rowid 作为表的主键。迁移的需求,有改变的风险。

  2. rownum

    列出每一行数据的行数,从1开始,自然增长。

    -- 基本用法
    select rownum, d.* from dept;
    select rownum, d.* from dept d where rownum < 3;     -- 显示前两条
    select * from (select rownum rn, d.* from dept d) t where t.rn = 3;   -- 只显示第三条
    select * from (select * from emp order by sal desc) where rownum<=3;  -- 显示 emp 表中工资前三位的雇员信息。
    

6.1.7 NULL

它是 Oracle 中非常特殊的一种类型。它表示不确定,表示没有值。并且它能转化成所有的类型。 向数据库中插入空字符串时,oracle 会把它自动转化为 null 类型。所以,在查询空字符的时候:

select * from n3 where s = '';

上面的语句是非法,不合适的。应该这样查:

select * from n3 where s is null;
select * from n3 where s is not null;

创建表的时候,为了约束插入的数据不能为空,应该在字段的后面写上 not null 约束。

create table n5 (s varchar2(20) not null);

跟 null 做任何的运算,结果仍然是 null.

select null + '' from dual;   -- null

6.2 运算符

6.2.1 算术运算符

加 / 减 / 乘 / 除

6.2.2 连接运算符

是用来连接字符串的。跟java中的 + 是一致的。

select 'abc' || ' bcd ' as 连接后的结果 from dual;
select d.dname || ' 部门' from dept d;

6.2.3 比较运算符

> / < / >= / <= / != / <> /IS NULL / Like / Between / In / Exsist

-- 判断 null 值
select * from n5 where s is null;
select * from n5 where s is not null;-- like 模糊查询。慎用,有可能会导致全表扫描,效率低。
-- % 匹配0到多个字符,_ 匹配一个字符
select username from dba_users where username like 'VI_';
select username from dba_users where username like 'SC%';
select username from dba_users where username like '%SC%';-- in,是 where x = a or x = b or x = c 的一种缩写。下面两条是等价的。
select * from emp where empno in (700, 800, 900);
select * from emp where empno = 700 or empno = 800 or empno = 900;
-- in 后面跟的不一定是逗号分隔的单项,也可能是一个完整的查询语句。
-- 下面两条结果是一致的
-- 这种 in 慎用
select * from emp where deptno in (select deptno from dept where dname = 'SALES');
select a.* from emp a,dept d where a.deptno =d.deptno and d.dname='SALES';-- between...and
select * from emp where empno between 7800 and 9000;
-- 等同于:
select * from emp where empno >= 7800 and empno <= 9000;

6.2.4 逻辑运算符

and / or / not

not 的优先级 > and 的优先级 > or 的优先级

6.2.5 集合操作符

Union / UnionAll / Intersect / Minus

-- 生成测试数据
create table dept_01 as select * from dept where rownum < 6;
create table dept_02 as select * from dept where rownum < 4;
insert into dept_02 values (98, '小吃部', '斗门');
insert into dept_02 values (99, '外卖部', '香洲');
commit;select * from dept_01
union
select * from dept_02;select * from dept_01
union all
select * from dept_02;select * from dept_01
intersect
select * from dept_02;select * from dept_01
minus
select * from dpet_02;

6.3 Join Query

-- 初始化表
create table loc (id int primary key, name varchar2(20));
create table person (name varchar2(20), locid references loc);-- 初始化数据
insert into gp values (1, '和平', '万岁');
insert into gp values (2, '自由', '很好');
insert into gp values (3, '民主', '爱国');
insert into gp values (4, '敬业', '友善');
insert into loc values (11, '广东');
insert into loc values (22, '山东');
insert into loc values (33, '湖南');
insert into loc values (44, '江西');
insert into person values ('王新炜', 33);
insert into person values ('吴英平', 33);
insert into person values ('杜志海', 44);
insert into person values ('范锐', 11);
commit;select * from person;
select * from loc;-- 查询就是一个逐步过滤的过程
-- 叉乘,内部杂交,虚拟表,16条数据
select * from person, loc;
-- 过滤掉不符合条件的数据。即完成一次外连接。
-- 即:增一表,加一条件。
select * from person, loc where person.locid = loc.id;
-- 其他条件,即在上面的基础上继续过滤
select * from person, loc where person.locid = loc.id and person.name like '王%';-- 增加另一个表
create table gp (id int primary key, name varchar2(20), logo varchar2(10));
alter table person add  (gpid int references gp);
-- 修改每个人的 group
-- update ..select * from gp;
select * from loc;
select * from person;update loc set name='中华人民共和国湖南省' where id=33;
commit;select * from person p, loc l, gp g;
-- 将不符合的排除掉
select * from person p, loc l, gp gwhere p.locid = l.idand p.gpid = g.id-- and   l.name = '江西'and g.name='和平'and p.name like '王%';--
-- oracle 写法,非标准
select * from person p, loc l, gp gwhere p.locid = l.id and p.gpid = g.id;-- ansi sql 写法,join 默认是 inner join
select * from person pjoin loc l on p.locid = l.idjoin gp g on p.gpid = g.id;-- 增加一个没有地区的人
insert into person values ('黄秀', null, null);
commit;-- 显示所有人,并将其地区信息查询出来。
-- 需要使用外连接,将即使不匹配的人也查询出来
-- oracle 写法
select * from person, locwhere person.locid = loc.id(+);
-- 标准写法
select * from person pleft outer join loc l on p.locid = l.id;

6.4 Functions

6.4.1 Numeric

  • abs/mod 绝对值/求模
  • sqrt/power/exp 求幂
  • ceil/floor/round 取整
  • trunc 截取小数点
  • sin/cos/ln/log 数学函数

6.4.2 Charactor

  • chr/ascii ascii码
  • length/lengthb 字符/字节长度
  • initcap/upper/lower 字母大小写
  • substr/translate/replace/instr 子串/替换
  • ltrim/rtrim/lpad/rpad 修剪/填充

6.4.3 Datetime

select sysdate, systimestamp, current_date from dual;
-- x 天之后的日期
select sysdate + 365 from dual;
-- x 个月后的日期
select add_months(sysdate, -5) from dual;
-- 相差几个月
select months_between(to_date('20180501'), sysdate) from dual;
-- 下周 x 的日期
select next_day(sysdate, '星期一') from dual;
select next_day(sysdate, 2) from dual;  -- 1 代表星期天, 0 代表星期一, 类推
-- 一个月的最后一天/第一天
select last_day(sysdate) from dual;
select trunc(sysdate,'MONTH') from dual;
select trunc(sysdate,'YEAR') from dual;
-- 获取日期的单个字段
select extract(day from sysdate) from dual;
-- 对日期进行截取
select round(to_date('20170916'),'MONTH') from dual; -- 四舍五入
select trunc(to_date('20170916'),'MONTH') from dual;

6.4.4 Nullable

  • nvl/nvl2/nullif

6.4.5 Miscellaneous

decode/case when:

-- 生成数据
create table sss (name varchar2(20), gender int);
insert into sss values ('樱桃小丸子', 2);
insert into sss values ('路飞', 1);
insert into sss values ('大熊', 3);
insert into sss values ('光头强', 1);
commit;-- 查询,将 gender 的数字转化为男女
-- 1. decode 函数的方式
select name, decode(gender, 1, '雄性',2, '雌性','未知性别') "性别" from sss;
-- 2. case when 的方式
select name, case genderwhen 1 then '雄性'when 2 then '雌性'else '未知性别'end "性别" from sss;-- 3. case when 的另一种方式
select name, case when gender <= 1 then '雄性'when gender >= 2 then '雌性'else '未知性别'end "性别" from sss;-- 给 emp 中的人加工资:
---- 1000 元以下的,加 50%
---- 2000 元以下的,加 30%
---- 3000 元以下的,加 20%
---- 其他人 5%
create table emp3 as select * from emp;
-- 如果要将所有的工资翻倍,这么写:
update emp3 set sal = sal*2;
-- 如果不同的人加不同的工资,需要用到 case when:
update emp3 set sal = (casewhen sal <= 1000 then sal*1.5when sal <= 2000 then sal*1.3when sal <= 3000 then sal*1.2else sal*1.05end);
-- 如果 1981/5/1 之前来公司的人按照上面调薪,其他人只调 1% 呢?
-- [TODO]

6.4.6 Aggregate Function

聚合函数是用来统计每个分组的统计信息,它们要跟 group by 一起使用,用来将每个分组所有数据 聚合 成一条统计数据。

包括 max/min/count/avg/sum 等。

-- 按照部门进行分组统计的语句
select deptno,             -- 因为按照 deptno 分组,select 中只能有 deptno 字段count(*),           -- 每个分组多少条数据max(sal),           -- 每个分组工资的最大值min(sal),           -- 每个分组工资的最小值avg(sal),           -- 每个分组工资的均值sum(nvl(comm, 0))   -- 每个分组奖金总和,因为奖金可能为 null,所以需要使用 nvl 进行去空from empgroup by deptno;          -- 分组依据-- 可以用 having 对结果进行过滤
-- 整个 select 语句执行顺序大致是: where -> group by -> having -> order by
select deptno, count(*), max(sal), min(sal), avg(sal), sum(comm)from empgroup by deptnohaving avg(sal) > 2000;-- having 等价于嵌套的 where,即上面语句跟下面这条等效。
select * from (select deptno, count(*), max(sal), min(sal), avg(sal) asal, sum(comm)from empgroup by deptno) where asal > 2000;

6.4.7 Analytic Function

https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions004.htm#SQLRF06174

聚合函数统计的是一个分组的信息,聚合之后每个分组只能得到一条信息,但并不能够获取分组内成员的具体信息。

而分析函数可以详细显示分组内部的统计信息,它显示的信息更全面,语法也更复杂。

大致来说,分析函数的使用语法是这样的:

分析函数() over ([partition by xxx] order by yyy [rows/range ...])

解释:

  • 一个分析函数,需要跟着一个窗口函数。
  • 以 over 开始的部分叫 窗口函数, 它描述了要对哪些数据、按照什么方式进行分析的行为。
  • 窗口函数内部分为三部分,其中 order by 是必须的,其它可选
  • partition by 指定了数据按照什么方式 分组/分区
  • order by 指定了在分区之内,数据的排序方式
  • rows/range 可以对分区的数据进行限定
  • 分析函数有很多,比如 row_number/rank/dense_rank/max/count 等,row_number 等有如下区别
    ROW_NUMBER 返回连续的排位,不论值是否相等
    RANK 具有相等值的行排位相同,序数随后跳跃
    DENSE_RANK 具有相等值的行排位相同,序号是连续的
    
  • 需要查询组本身的信息,用聚合函数 group by; 需要查询组成员的统计信息,需要用分析函数。

示例:

-- 最基本,窗口描述内只有 order by
select e.*, sum(sal) over (order by sal) from emp e;
select e.*, row_number() over (order by sal) from emp e;-- 以组为单位,进行排序
select e.*, sum(sal) over (partition by deptno order by sal) from emp e;
select e.*, row_number() over (partition by deptno order by sal) from emp e;-- 比如,要查询每个组的最高工资,可以用聚合函数
select deptno, max(sal) from emp group by deptno;
-- 但如果要查看工资最高的那个人,聚合函数无能为力,需要用到分析函数
---- 1. 首先按组排序
select e.*, row_number() over (partition by deptno order by sal desc) from emp e;
---- 2. 过滤,只取排名第一的那个人,ok
select * from(select e.*, row_number() over (partition by deptno order by sal desc) rn from emp e)where rn = 1;

6.5 Pagination

使用 rownum 或者 row_number():

-- 注意,这种写法是无效的,因为:rownum > n 这种写法无意义
select * from emp where rownum > 4 and rownum < 8;-- 为了能使用 rownum>n,我们只需要嵌套一层查询即可
select *from (select rownum rn, e.* from emp e)where rn > 4and rn < 8;-- 同样,使用 row_number() 分析函数,我们也需要嵌套一层
select *from (select row_number() over(order by rowid) rn, e.* from emp e)where rn > 4and rn < 8;-- 而下面这种写法,基本上是最合理,最高效的:
select * from (select a.*, rownum rn from (select * from emp) a where rownum < 8)where rn > 4;-- 即:
SELECT * FROM (SELECT a.*, ROWNUM rn FROM (-- 要查询的语句) a where ROWNUM < '#最大序号#')WHERE rn > '#最小序号#';

6.6 查询语句执行顺序

完整的查询语句类似是这样的:

select ..., ROWNUMfrom tablewhere <where clause>group by <columns>
having <having clause>order by <columns>;

它的处理顺序是:

  1. 首先,执行 FROM/WHERE 语句
  2. 为结果赋予 ROWNUM 并同时根据 FROM/WHERE 语句进行 rownum 过滤
  3. 执行 SELECT
  4. 执行 GROUP BY
  5. 执行 HAVING
  6. 执行 ORDER BY

PS: 如果存在分析函数(row_number etc),那么,分析函数的执行会在 order by 之前。

6.7 DDL/DML/TCL/DCL

表的约束:

  • 是加在表上的一种对象,能保证每次插入或修改数据的时候,对数据的合法性进行检查,从而避免插入不合理数据。
  • 优点:通过检查,能保证数据的完整性和一致性。
  • 缺点:消耗一定的存储,数据量大的时候,每次检查会有一定的资源损耗
-- 首先,创建表:类型、长度、非空
create table ddl_test1 (id int,name varchar2(20) not null,birthday date,sex int
);-- 在表 ddl_test1 上增加一个名字为 fk_ddl_sex_01 的约束
-- 作用在 sex 列上 / 关联到 ddl_sex 表的 id 列
alter table ddl_test1add constraint fk_ddl_sex_01 foreign key (sex) references ddl_sex (id);create table ddl_sex (id int,value varchar2(10)
);alter table ddl_sex add constraint pk_ddl_sex primary key(id);
select * from ddl_sex;---- 创建约束的几种方式
---- 第一种方式,先创建表,再初始化数据,最后再加约束
-- 创建表
create table ddl_test2 (id int,name varchar2(20) not null,birthday date,sex int
);
create table ddl_sex2 (id int,value varchar2(10)
);
-- 插入数据
insert into ddl_sex values (1, '男');
insert into ddl_sex values (2, '女');
insert into ddl_test2 values (2, 'xx', sysdate, 1);
insert into ddl_sex values (3, '不知');
insert into ddl_test2 values (1, 'xx', sysdate, 1);
insert into ddl_test2 values (3, 'xx', sysdate, 1);
insert into ddl_test2 values (4, 'xx', sysdate, 1);
-- 增加约束
alter table ddl_test2 add constraint fk_0023 foreign key (sex) references ddl_sex;
alter table ddl_test2 add constraint pk_test2 primary key (id);---- 第二种方式,在建表的字段上直接建立约束
create table ddl_test4
( id int primary key,name varchar2(20) not null,sex constraint hello250 references ddl_sex
);---- 第三种方式,将建立约束的语句,放到建表语句最后。优点,清晰易于管理。
create table ddl_test5
(id int,name varchar2(20) not null,sex int,constraint hello260 primary key(id),foreign key (sex) references ddl_sex);---- 约束的种类
---- 主要有:主键约束、非空约束、唯一约束、检查约束、外键约束等
create table ddl_test6 (id int,sal number(5)
);
alter table ddl_test6 add constraint pk_test6 primary key (id);
alter table ddl_test6 add constraint ck_2323 check(sal > 1250);
insert into ddl_test6 values (1, 500);
insert into ddl_test6 values (2, 3500);
select * from ddl_test6;

表的命名:

另外:

  1. 表名等在数据库内部会自动转化为大写的形式。如果想使用小写的形式,需要在创建的时候,加双引号。

    create table "lowcase_name" (...);
    
  2. 表名尽量使用英文单词,或英文单词缩写词。如果有多个单词连接,请使用下划线。
  3. 不要使用复数形式。比如使用 boy 而不是 boys, 使用 student 而非 students.
  4. 字段名字有两种方式:
    -- 清晰明了不拖泥带水,但多表联合查询,可能出现重复字段
    create table boy (id int, name varchar2(20), wechat varchar2(20));
    -- 写法丑,但联合查询不会出现重复字段
    create table girl (girl_id int, girl_name varchar2(20), girl_wechat varchar2(20));
    

  5. 主键请使用 代理主键, 即没有任何业务关联的字段作为主键。因为直觉上不变的东西,在特定情况下都可能发生变化。
  6. 自增,请使用 序列, 最好为每个单独的主键创建一个专用的序列。
    -- 首先,保证有创建序列的权限
    GRANT CREATE SEQUENCE TO VIP;-- 创建序列的最简语句
    -- 注意,命名中,最好带 seq 等字段,表示这是一个序列
    CREATE SEQUENCE seq_boy;-- 使用的方式很简单
    insert into boy values (seq_boy.nextval, 'xxx');
    select seq_boy.currval  -- 序列当前值seq_boy.nextval  -- 序列下一个值from dual;-- 序列可以有更多参数
    create sequence seq_boy2minvalue 2      -- 最小值,默认 1maxvalue 1000   -- 最大值,默认无限start with 4    -- 初始值,默认跟 minvalue 相同increment by 2  -- 步进nocycle         -- 如果到达最大值,是否从开始再次循环nocache         -- 设置缓存;-- 修改
    alter sequence seq_boy2 cache 10;
    alter sequence seq_boy2 maxvalue 2000 increment by 5;-- 删除
    drop sequence seq_boy2;
    

修改, ALTER:

-- 创建示例表
create table ddl_test1
(id int primary key,name varchar(2) not null,birth date default sysdate
);-- 各种修改
alter table ddl_test1 rename column id to testid;
alter table ddl_test1 modify (name varchar2(40), birth timestamp);
alter table ddl_test1 add gender varchar2(10) not null;
alter table ddl_test1 drop column gender;-- 作用在序列上的 DDL
create sequence seq_aaa;
alter sequence seq_aaa start with 222;
drop sequence seq_bbb;

查询, select:

-- SELECT 语句中的基本计算,是基于行的
-- 不同行中的数据,不能直接计算
-- 所以,解决的方案是:将不同行的数据整合到同一行中,再做比较
-- 而整合到同一行,有很多方法:
-- 可以是表跟表进行关联;可以是分组;等等。
-- 关键是:思路,思路,思路。-- 下面是一个例子
-- 查询男、女之差-- 首先,初始化数据
-- 男 / 46人
-- 女 / 10人
create table aaa (gender char(2), num number);
insert into aaa values ('男', 46);
insert into aaa values ('女', 10);-- 1. 这是一种方法,
witha as (select * from  aaa where gender = '男'),b as (select * from  aaa where gender = '女')
select a.num - b.num from a, b;-- 2. 下面是上面方式的等价写法
select a.num - b.numfrom (select * from aaa where gender = '男') a,(select * from aaa where gender = '女') b;-- 3. 下面是另一种写法
select (select num from aaa where gender = '男') - num from aaa where gender = '女';-- 4. 最基本的,对表进行关联查询,之后再过滤,再计算
select a.num - b.num from aaa a, aaa b where a.gender='男' and b.gender='女';-- 5. 或者基于分组
select max(num) - min(num) from aaa;-- 6.7.8. 其他方法...

SQL语句和sql函数相关推荐

  1. SQL语句--简单的函数书写举例(3)

    SQL语句–简单的函数书写举例(3) 在前两篇中,案例只涉及到简单的数值,这样的函数称为[标量函数] 这里的函数,可以简单的理解为它是一个可以进行计算的工具 标量函数:是简单的数值,eg:int.ch ...

  2. SQL语句--简单的函数书写举例(1)

    SQL语句–简单的函数书写举例(1) 在数据库下的[可编程性]–[函数]下可看到有4类函数,平时用的函数大部分为[系统函数]下的,当这些函数不能满足实际需求时,我们要自己创建函数. eg:计算 A+B ...

  3. sql语句insert插入函数如果values值括号里放变量名

    sql语句insert插入函数如果values值括号里直接放变量名就会到时表增加了一个空的记录,解决方法是使用特殊格式 String sql = "insert into user(name ...

  4. sqlserver sql语句|经典sql语句|实用sql语句

    sqlserver sql语句|经典sql语句|实用sql语句 一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop databa ...

  5. 学习SQL语句之SQL语句大全

    学习SQL语句之SQL语句大全 -------------------------------------------------------------------------------- 作者: ...

  6. SQL语句集锦,SQL语句大全

    SQL语句集锦/SQL语句大全 --语 句 功 能 --数据操作 SELECT --从数据库表中检索数据行和列 INSERT --向数据库表添加新数据行 DELETE --从数据库表中删除数据行 UP ...

  7. Pycharm中SQL语句提示SQL Dialect is Not Configured

    使用Pycharm进行数据库查询时,SQL语句提示SQL Dialect is Not Configured,是因为没有配置数据库. 按照图中设置即可. File --> Settings -- ...

  8. 常用的sql语句,sql使用大全

    常用的sql语句,sql使用大全 我工作中常用到的sql 插入 查询 更新 介绍其他的sql SQL分类 基本的sql语句 高级查询运算词 我工作中常用到的sql 下面是我工作中常用的sql,每次都是 ...

  9. SQL语句教程-------SQL语法

    SQL语句教程-------SQL语法 在这一页中,我们列出所有在这个网站有列出 SQL 指令的语法.若要更详尽的说明,请点选指令名称. 这一页的目的是提供一个简洁的 SQL 语法做为读者参考之用.我 ...

  10. oracle sql语句备份数据库,用SQL语句备份SQL数据库_oracle

    备份数据库的命令是: BACKUP DATABASE test TO disk = 'c:/test' WITH FORMAT, NAME = 'Full Backup of MyNwind' 解释如 ...

最新文章

  1. antd Tree 展开和默认选中
  2. AWK神器,继续案例
  3. 用按位异或运算符交换两个数,不引入第三个变量
  4. ssh证书登录(实例详解)
  5. 【数据使用】3问视觉项目中的数据整理,这点小事你是不是都掌握好了?
  6. android rfid 数据解析_手持机是什么?RFID手持机是什么?
  7. 数据契约(DataContract)
  8. 搜狗输入法语音转文字的体验点
  9. day20---IO流概述
  10. 打造颠覆你想象中的高性能,轻量级的webform框架-----如何替换webform的垃圾控件(第一天)...
  11. libsvm 参数以及计算测试点相似度
  12. 跟着莫烦python 从零开始强化学习之Q-Learning 一维探索者 代码完整注释版
  13. 英文文献下载神器—Scihub
  14. 探秘Google新搜索引擎算法
  15. 这5个是不是元宇宙游戏遗珠?
  16. IE无法打开internet站点已终止操作的解决办法
  17. mysql 导入 没有数据库文件怎么打开_没有SQL Server数据库时如何打开.MDF文件
  18. 酷派 手机 stop charging
  19. Excel VBA:数据管理与维护
  20. CSR867x — Speaker Equalizer曲线调试笔记

热门文章

  1. 网上买包包首选的3个网站(必看的3个包包网站)
  2. Scrapy学习第四课
  3. unity pico3 手柄摇杆控制物体移动和旋转
  4. python 读取行数据_openpyxl读取所有行数据之rows属性
  5. Android 全面屏处理(适配挖孔屏、刘海屏) kotlin
  6. ASPWEB编程开发常用的代码
  7. PCB中MARK点画法与注意事项
  8. 水星mw150us linux驱动下载,水星MW150US驱动
  9. 强迫症患者之黑苹果优化(启动画面、CPU重命名、显示真实主板、开启12代CPU全核心)
  10. 北京交通大学计算机学院硕士导师,北京交通大学计算机与信息技术学院研究生导师:王涛...