Oracle和Mysql的区别
ps: 我用docker拉了一下2者的镜像,mysql大小545M,oracle11g则需要6.85G
常用的字段类型不一样
拓展说明:
时间的字段类型不一样
-- 第一步:创建序列(ps: 也可以通过navicat创建)
create sequence SEQ_T_LOCALOBTMIND
-- 验证序列是否能成功取到值
select SEQ_T_LOCALOBTMIND.nextval from dual
-- 第二步:设置触发器(ps: 请确保表名、字段都是大写的,否则触发器执行会失败)
create or replace trigger T_LOCALOBTMIND_INSERT_ID
before insert on "T_LOCALOBTMIND" for each row
begin
select SEQ_T_LOCALOBTMIND.nextval into:NEW.ID from dual;
end;
-- 第三步:测试
INSERT INTO "T_LOCALOBTMIND"("DDATETIME", "OBTID", "WDIDF") VALUES (TO_DATE('2021-06-03 08:22:04', 'SYYYY-MM-DD HH24:MI:SS'), 'G1121', '11.34');
-- 查第10-20条记录。10、20个数字表示记录的行号
select * from (
SELECT emp.*, rownum as rowno from emp
)t_target
where rowno >= 10 and rowno < 20
-- 查第10-20条记录。第一个10表示起始下标,第二个10表示取多少条记录
SELECT * FROM `tb_user`
limit 10, 10
时间相减
select TO_DATE('2021-05-30 15:51:20', 'yyyy-mm-dd hh24:mi:ss') -7 from dual;
-- 计算前7天,结果:2021-05-23 15:51:20
select TO_DATE('2021-05-30 15:51:20', 'yyyy-mm-dd hh24:mi:ss') - 1/24 from dual;
-- 计算前1个小时,结果:2021-05-30 14:51:20
select date_sub('2021-05-30 21:00:40' ,interval 7 day)
-- 计算前7天,结果:2021-05-23 21:00:40
select date_sub('2021-05-30 21:00:40' ,interval 1 hour)
-- 计算前1个小时,结果:2021-05-30 20:00:40
timestamp类型的时间相减
SELECT MIN_T, MAX_T, MAX_T - MIN_T
FROM "T_TIMESTAMP"
-- 结果:2021-07-06 20:29:20.000000 2021-07-07 20:29:22.000000 +000000001 00:00:02.000000
SELECT min_t, max_t, TIMESTAMPDIFF(second,min_t,max_t) FROM `t_timestamp`
-- 结果:
2021-07-03 21:01:22 2021-07-04 21:01:22 86400
2021-07-04 21:02:01 2021-07-04 21:02:06 5
2021-07-04 21:03:58 2021-07-04 21:04:01 3
字符串转时间
select TO_DATE('2021-05-30 15:51:20', 'yyyy-mm-dd hh24:mi:ss') from dual;
-- 24小时制的转换,结果:2021-05-30 15:51:20
select TO_DATE('2021-05-30 下午 11:51:20', 'yyyy-mm-dd am hh12:mi:ss') from dual;
-- 12小时制的转换,结果:2021-05-30 23:51:20
select STR_TO_DATE('2021-05-30 15:51:20','%Y-%m-%d %H:%i:%s');
-- 结果:2021-05-30 15:51:20
-- tip: myql的这个格式,也不难记,Y、m、d、H、i、s,只要记住有2个字母是大写的就好了
时间转字符串
select to_char(current_date, 'yyyy-mm-dd hh24:mi:ss') from dual;
-- 24小时制的转换,结果:2021-05-30 16:06:52
select to_char( TO_DATE('2021-05-30 15:51:20', 'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd am hh12:mi:ss') from dual;
-- 12小时制的转换,结果:2021-05-30 下午 03:51:20
select DATE_FORMAT(current_timestamp,'%Y-%m-%d %H:%i:%s');
-- 结果:2021-05-30 16:10:14
查询当前的日期+时间
select CURRENT_TIMESTAMP from dual;
-- 结果:2021-05-30 16:19:10.640466 +08:00
select current_date from dual;
-- 结果:2021-05-30 16:16:54
select SYSDATE from dual;
-- 结果:2021-06-07 20:54:57
select CURRENT_TIMESTAMP;
-- 结果:2021-05-30 16:21:16
select now();
-- 结果:2021-05-30 16:17:41
-- 我一般用这个,比较简单,好记忆
select sysdate()
-- 结果:2021-06-07 20:55:38
引号的用法
select concat('%', 'G1120') from dual
-- 结果:%G1120
select concat("%", 'G1120')
-- 结果:%G1120
空字符串的情况
大小写区分
-- 如果表名用引号包裹,则区分大小写
CREATE TABLE "TUSER"."t_localobtmind2" (
"ID" NUMBER,
"DDATETIME" DATE,
"OBTID" VARCHAR2 ( 20 ),
"WDIDF" NUMBER ( 10, 2 )
)
-- 结果:生成了一张 t_localobtmind2 的表
-- 默认生成的表名是大写的
CREATE TABLE t_localobtmind3 (
"ID" NUMBER,
"DDATETIME" DATE,
"OBTID" VARCHAR2 ( 20 ),
"WDIDF" NUMBER ( 10, 2 )
)
-- 结果:生成了一张T_LOCALOBTMIND3的表
-- 默认是小写的,无论你是否用引号包裹,生成的表名都是小写的
CREATE TABLE T_TYPE3 (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c_date` datetime DEFAULT NULL,
`c_time` time DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-- 结果:生成了一张 t_type3 的表
CREATE TABLE `T_TYPE4` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c_date` datetime DEFAULT NULL,
`c_time` time DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-- 结果:生成了一张t_type4的表
tip: 虽然,网上有的地方说,oracle也有if的用法,不过那个只适用于存储过程存储函数,不适用于单条sql执行
-- decode()函数
select DECODE(2,
1, '风速',
2, '雨量',
3, '浪高',
null)
from dual;
-- 结果:
雨量
-- case when的写法1:公式匹配
select sal, CASE
when sal >= 5000 then '高薪'
when sal >= 2000 then '中薪'
WHEN sal > 800 THEN '低薪'
ELSE '其它'
END as cn
from emp;
-- 结果:800 其它
1600 低薪
1250 低薪
2975 中薪
...
-- case when的写法2:值匹配
select sal, CASE sal
when 5000 then '高薪'
when 1600 then '中薪'
WHEN 800 THEN '低薪'
ELSE '其它'
END as cn
from emp;
-- 结果:
800 低薪
1600 中薪
1250 其它
2975 其它
...
mysql的条件判断,貌似只有case when这一种比较合适的选择
-- mysql也有decode()函数,不过是用来加密字符串的
select @savePwd:= ENCODE('admin123','diy_key');
select DECODE(@savePwd,'diy_key');
-- 结果:(BLOB) 8 bytes
-- 如果在navicat里面,选择查看-文本,能看到是 admin123
`
-- case when的写法1:公式匹配:
set @var = 2001;
select CASE
WHEN @var >= 5000 THEN '高薪'
when @var >= 2000 then '中薪'
when @var >= 800 then '低薪'
ELSE '其它'
END as cn
-- 结果:中薪
-- case when的写法2:值匹配
-- select @var := 2;
set @var = 2;
select CASE @var
WHEN 1 THEN
'一'
when 2 then
'二'
ELSE
'其它'
END as cn
-- 结果:二
-- mysql的简单条件判断
set @factory=1;
select IF(@factory=1,'风速','其它要素')
-- 结果:
风速
select rownum, username from all_users;
-- 结果:
1 TUSER
2 TEST
3 BI
4 PM
5 SH
6 IX
7 OE
8 HR
9 SCOTT
10 OWBSYS_AUDIT
SELECT
@rowno:=@rowno+1 as rowno,
t_data.*
from
user_info t_data ,
(select @rowno:=0) t_init;
-- 结果:
1 3 wanger 2 2021-01-31 22:02:18
2 5 aaa 2232 2021-01-31 22:02:17
select to_char(211.125456,'99999999999990.99') from dual;
-- 需要四舍五入的情况,结果:211.13
select to_char(211.1,'99999999999990.99') from dual;
-- 小数位不够2位的情况,结果:211.10
select to_char(0,'99999999999990.99') from dual;
-- 特殊值0的情况,结果:0.00
select FORMAT(211.125,2);
-- 需要四舍五入的情况,结果:211.13
select FORMAT(211.1,2);
-- 小数位不够2位的情况,结果:211.10
select FORMAT(0,2);
-- 特殊值0的情况,结果:0.00
select current_date from dual;
-- 结果:2021-05-30 16:16:54
select now();
-- 结果:2021-05-30 16:17:41
oracle行转列,需要借助connect by语法和regexp_substr()函数
select REGEXP_SUBSTR(codes, '[^,]+', 1, rownum) from(
select 'G1120,G1121,G1122,G1123' as codes from dual
) t_base
connect by rownum <= LENGTH(codes) - LENGTH(REPLACE(codes, ',', '')) + 1
-- 结果:
G1120
G1121
G1122
G1123
-- 分析:regexp_substr() 这个函数,可以通过正则去截取某个字符串里面的内容。第一个参数是源字符串,第二个参数是正则表达式,也就是截取规则,第三个参数表示从第几个字符开始匹配正则表达式,第四个参数表示第几个匹配内容
-- 结果:
G1120
G1121
G1122
G1123
-- 字符串正则分割
SELECT
REGEXP_SUBSTR ('G1120,G1121,G1122,G1123', '[^,]+', 1,2) code
from dual
-- 结果:
G1121
-- 返回第2次匹配到的内容
-- 生成数字序列结果集
select rownum from dual
connect by rownum <= 3;
-- 结果:
1
2
3
mysql的行转列,需要借助 join中on<的特殊用法和substring_index()函数
select SUBSTRING_INDEX(subStr,',', -1) code from(
select
codes, help_topic_id, SUBSTRING_INDEX(codes,',',help_topic_id + 1) subStr
from
(
select 'G1120,G1121,G1122,G1123' as codes
) t_base
inner join mysql.help_topic t_help
on t_help.help_topic_id <= LENGTH(t_base.codes) - LENGTH(REPLACE(t_base.codes,',',''))
) t_with_id
-- 思路:
-- 通过mysql的一张行转列的辅助表来做,tip: 那张表最多643条记录哦
-- LENGTH(REPLACE(t_code.codes,',','')表示,除去逗号,还有多少个字符
-- LENGTH(t_code.codes) - LENGTH(REPLACE(t_code.codes,',','')) 表示有多少个逗号
-- 第一个SUBSTRING_INDEX()函数,得到的内容,分别是:
G1120
G1120,G1121
G1120,G1121,G1122,
G1120,G1121,G1122,G1123
-- 第二个SUBSTRING_INDEX()函数,得到的内容,分别是:
G1120
G1121
G1122,
G1123