Mysql 与 Oracle 基本语法的对照
函数类型 | oracle(11g) | mysql(8.0.20) | 语法 | 例子 |
窗口函数 | over() | over() | 一致 Over()窗口函数最常见的搭配有以下几种: 1. rank(),dense_rank(),row_number() + over(partition by … order by …) 排名 2. sum(),avg(),count()聚合函数+over(partition by … order by …) 3. max(),min()+over(partition by … order by …) 最大值、最小值 4. first_value(),last_value() + over(partition by … order by …) 第一条、最后一条记录 5, lag(),lead() + over(partition by … order by …) 偏移量 |
Mysql与Oracle一致:
select a.department_name,a.id,a.sal,
select a.department_name,
select a.*, |
数值 | round(), ceil(), floor(), trunc(), |
round(), ceil()/ceiling(), floor(), truncate(), |
保留有效位数的函数基本一致。只有trunc和truncate函数名称不一致 | Mysql: Oracle: |
max()/min() | max()/min() | 计算最大最小值的函数一致 | ||
字符串函数 | '' | '' 或者 "" | Mysql里可以用双引号包起字符串,Oracle里只可以用单引号包起字符串。在插入和修改字符串前必须做单引号的替换:把所有出现的一个单引号替换成两个单引号。 | |
SUBSTR('ababababab',2,5) | SUBSTR('ababababab',2,5) /SUBSTRING('ababababab',2,5) | 截取字符串的函数一致。Mysql 的substr()与substring()两种写法都可以. 区别:oracle的SUBSTR('ababababab',0,5)和SUBSTR('ababababab',1,5) 从0开始或者从1开始都表示从1开始。Mysql只能从1开始,不支持0 |
Mysql: select SUBSTR('ababababab',2,5) ; select SUBSTRING('ababababab',2,5) ; Oracle: select substr('ababababab',2,5) from dual; |
|
replace('ababababab','b','c') | replace('ababababab','b','c') | 一致 替换字符串函数,在字符串 str 中所有出现的字符串 from_str 均被 to_str 替换,然后返回这个字符串. | Mysql: select replace('ababababab','b','c') Oracle: select replace('ababababab','b','c') from dual; |
|
instr('ababababab','b',5) | INSTR('ababababab','b' ) | 获取位置的函数,用法基本一致,但是参数个数不同 ORACLE: select instr('ababababab','b',5) value from dual(要求从位置5开始) MYSQL: select INSTR('ababababab','b' ) value(从默认的位置1开始) |
ORACLE: select instr('ababababab','b',5) value from dual(要求从位置5开始) MYSQL: select INSTR('ababababab','b' ) value(从默认的位置1开始) |
|
LENGTH('ababababab') | LENGTH('ababababab') CHAR_LENGTH('ababababab') |
获取字符串长度的函数,用法一致 | Mysql: select LENGTH('ababababab'); select CHAR_LENGTH('ababababab'); Oracle: SELECT length('ababababab' ) FROM DUAL; |
|
LPAD('abcd',14, '0') RPAD('abcd',14, '0') |
LPAD('abcd',14, '0') RPAD('abcd',14, '0') |
从左或者右,使用给定字符,补齐位数。用法一致 | Mysql: select LPAD('abcd',14, '0') ; select RPAD('abcd',14, '0') ; Oracle: select LPAD('abcd',14, '0') from dual; select RPAD('abcd',14, '0') from dual; |
|
upper('abcd') lower('ABCD') |
upper('abcd') lower('ABCD') |
转换大小写。用法一致 | Mysql: select upper('abcd') ; select lower('ABCD') ; Oracle: select upper('abcd') from dual; select lower('ABCD') from dual |
|
CONCAT('111','2222') | CONCAT('111','2222','333') | 拼接字符串函数,oracle的concat只支持两个字符,mysql的支持多字符。Oracle可以用‘||’来实现。例如:select '111'||'2222'||'333' from dual;两个数据库还有一个不同的地方。Mysql的concat函数只要里面一个参数为null整个拼成的就是null。而oracle只要一个参数不是null就不会拼成null。 | Mysql: SELECT CONCAT('111','222','333',null); Oracle: select '111'||'2222'||'333' from dual; select concat('11',NULL) from dual; |
|
|| | concat_ws(',','11','22','33') | 拼接字符串函数,带分隔符。Oracle没有此函数,可以用listagg或者|| | SELECT concat_ws(',','11','22','33') | |
listagg() | group_concat() | Mysql: group_concat()函数: 功能:将group by产生的同一个分组中的值连接起来,返回一个字符串结果。 语法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator '分隔符'] ) 通过使用distinct可以排除重复值;如果希望对结果中的值进行排序,可以使用order by子句;separator是一个字符串值,缺省为一个逗号。 Oracle: listagg()函数: 语法:listagg(合并的字段, 分隔符) WITHIN GROUP(ORDER BY 排序字段) group by 分组的字段 (1). 必须得分组,也就是说group by是必须的。 (2). listagg函数的第一个参数是需要显示的字段,也就是log_name;第二个参数是数值之间的分隔符;同时还需要进行排序和分组within group (order by name) |
Mysql: group_concat()函数: select a.class_id,group_concat(c_name,'(',a.num,')','人' order by c_name separator ' || ') from LX_20200218 a group by a.class_id; Oracle: listagg()函数: select a.class_id, listagg(a.c_name|| '(' || a.num || ')' || '人', ',') WITHIN GROUP(ORDER BY a.c_name) from lx_20200218 a group by a.class_id |
|
TRANSLATE() | replace() | Oracle里的TRANSLATE()与replace()类似,都是起到替换的作用。但是TRANSLATE()可以同时替换多个(单一)字符。 例如: select TRANSLATE('aaabbbcccaaa','ab','v') from dual; ---分别对a和b进行替换,a替换为v,b替换为空 结果: vvvcccvvv select replace('aaabbbcccaaa','ab','v') from dual; ---按照ab组合来替换为v 结果:aavbbcccaaa Mysql里没有TRANSLATE()函数,只能用replace函数嵌套。 |
1.translate 与replace类似是替换函数,但translate是一次替换多个单个的字符。 2.基本用法,字符对应替换。 例子: select translate('1234567','123' ,'abc') from dual ;--1替换为a,2替换为b,3替换为c 结果:abc4567 。 3.如果 没有对应字符则替换为null; select translate('1234567','123' ,'ab') from dual;--3替换为null; 结果:ab4567. 4.如果对应字符过多,不影响 select translate('1234567','123' ,'abccd') from dual; 结果:abc4567 5.如果替换字符整个为空字符 ,则直接返回null select translate('1234567','123' ,'') from dual; 结果:null; 6.如果想筛掉对应字符,应传入一个不相关字符,同时替换字符也加一个相同字符; select translate('1234567','&123' ,'&') from dual; 结果:4567; 7,如果相同字符对应多个字符,按第一个; select translate('12334567','1233' ,‘abcd') from dual; 结果:abcc4567; 8,如果想保留某些特定字符筛选掉其他的,比如筛掉汉字保留数字 先把数字筛选掉, select translate('你师看了3三楼2的6开8发','#0123456789' ,'#') from dual 再用筛选出的汉字去筛选原来的语句留下数字, select translate('你师看了3三楼2的6开8发','#'||translate('你师看了3三楼2的6开8发','#0123456789' ,'#'),'#') from dual; 结果:3268; |
|
INITCAP | 无 | oracle: 将参数arg1转换为每个单词的首字母大写的格式. Mysql没有此函数,只能自定义。利用空格分割字符串然后首字母再大写 |
select INITCAP('hello world') from dual; INITCAP('HELLOWORLD') --------------------- Hello World |
|
trim() | trim() | 两者用法一致 用法: 1. trim(‘ aaa ’)去除字符串左右两端的空格 2. 去除指定字符 SELECT trim(BOTH 'a' from 'aaabbbbaaa');--左右两端 SELECT trim(LEADING 'a' from 'aaabbbbaaa');--左侧 SELECT trim(TRAILING 'a' from 'aaabbbbaaa');--右侧 |
Mysql: SELECT trim(BOTH 'a' from 'aaabbbbaaa'); SELECT trim(LEADING 'a' from 'aaabbbbaaa'); SELECT trim(TRAILING 'a' from 'aaabbbbaaa'); Oracle: SELECT trim(BOTH 'a' from 'aaabbbbaaa') from dual; SELECT trim(LEADING 'a' from 'aaabbbbaaa') from dual; SELECT trim(TRAILING 'a' from 'aaabbbbaaa') from dual; |
|
ltrim/rtrim | ltrim/rtrim | mysql: ltrim/rtrim只能去除左右两侧的空格 oracle ltrim/rtrim不仅可以去除空格,也可以去除指定字符,达到(SELECT trim(LEADING 'a' from 'aaabbbbaaa');--左侧 和 SELECT trim(TRAILING 'a' from 'aaabbbbaaa');--右侧 ) 一样的效果 |
Mysql: select ltrim(' abd');---去除左空格 select ltrim('abd ');---去除右空格 Oracle: select ltrim(' abd') from dual;---去除左空格 select ltrim('abd ') from dual;---去除右空格 select ltrim('aaabd','a') from dual;---去除左侧开始的a字符 select ltrim('abdddd','d') from dual;---去除右侧开始的d字符 |
|
rpad()/lpad() | rpad()/lpad() | 用法一致 语法: RPAD(arg1,n,arg3) 在字符串arg1右边连续重复填充arg3直到填充后的字符串总长度到达n为止. LPAD(arg1,n,arg3) 在字符串arg1左边连续重复填充arg3直到填充后的字符串总长度到达n为止. |
Mysql: select rpad('thr',10,'ee') ;---threeeeeee select lpad('thr',10,'ee') ;---eeeeeeethr Oracle: select rpad('thr',10,'ee') from dual; ---threeeeeee select lpad('thr',10,'ee') from dual; ---eeeeeeethr |
|
REVERSE | REVERSE | 用法一致: 反转字符串 reverse(str) |
Mysql: select reverse('123') ;---321 Oracle: select reverse('123') from dual; ---321 |
|
无 | REPEAT(str, count) | Mysql的REPEAT(str, count)的函数,将字符串str重复count次后返回。例如: select REPEAT('123',4) 将‘123’重复四遍。 虽然oracle没有相关函数,但是可以通过rpad来实现。Rpad('123',12,'123')计算好位数,用‘123’来补齐 |
Mysql: select REPEAT('123',4) ; ----123123123123 |
|
日期函数 | sysdate | now()\CURDATE() | Mysql: now() 获取当前日期的年月日时分秒 CURDATE()获取当前日期的年月日 Oracle: sysdate 获取当前日期的年月日时分秒 |
Mysql: select now(); ---2020-12-11 11:16:59 select CURDATE(); ---2020-12-11 Oracle: select sysdate from dual ----2020/12/11 11:13:29 |
Oracle时间格式:yyyy-mm-dd hh:mi:ss | Mysql时间格式:%Y-%m-%d %H:%i:%s | |||
to_char(sysdate,'day') | DAYOFWEEK()/WEEKDAY()/ DAYNAME() | 获取星期 Mysql: 1. dayofweek(): 返回日期date的星期索引(1=星期天,2=星期一, ……7=星期六) 2. WEEKDAY(); 返回date的星期索引(0=星期一,1=星期二, ……6= 星期天) 3. DAYNAME() 返回星期的名字 oracle: to_char(sysdate,'day')返回字符串类型的星期一、星期二……星期日 |
Mysql: select WEEKDAY(date '2020-12-11') ----4 select DAYOFWEEK(date '2020-12-11')----6 select DAYNAME(date '2020-12-11')-----Friday Oracle: select to_char(date '2020-12-11','day') week_cn from dual -----星期五 select to_char(date '2020-12-11','day','NLS_DATE_LANGUAGE=AMERICAN') week_cn from dual ;---friday |
|
to_char(sysdate,'dd') | DAYOFMONTH() | 获取date在当前月份中天数 不同: DAYOFMONTH() 返回 int; to_char(sysdate,'dd') 返回字符串 |
Mysql: SELECT DAYOFMONTH(date '2020-12-11'); -----11 Oracle: select to_char(date '2020-12-11','dd' ) week_cn from dual ; -----11 |
|
to_char(date '2020-12-11','ddd' ) | DAYOFYEAR() | 获取date在当年的天数 不同: DAYOFYEAR() 返回int; to_char(sysdate,'ddd') 返回字符串 |
Mysql: select DAYOFYEAR(date '2020-12-11'); -----346 Oracle: select to_char(date '2020-12-11','ddd' ) week_cn from dual ; -----346 |
|
to_char(date '2020-12-11','mm' ) | MONTH() | 获取当前月份 | Mysql: select MONTH(date '2020-12-11')-----12 Oracle: select to_char(date '2020-12-11','mm' ) from dual ; -----12 |
|
to_date('2020-12-11','yyyy-mm-dd') | STR_TO_DATE('2020-12-11', '%Y-%m-%d') | 字符串转日期 注意Mysql在转日期时候的格式%Y Y要大写 | Mysql: SELECT STR_TO_DATE('2019-01-20', '%Y-%m-%d'); Oracle: select to_date('2020-12-11','yyyy-mm-dd') from dual |
|
date'2020-12-11'+1/date'2020-12-11'-1 | DATE_SUB/DATE_ADD() | 日期计算 Oracle支持日期直接计算。但是mysql不能使用date'2020-12-11'+1,他的结果为数值型。 Mysql使用DATE_SUB/DATE_ADD()函数来计算。可以搭配SECOND、MINUTE、HOUR、DAY、WEEK、MONTH、QUARTER、YEAR 等等; |
Mysql: select DATE_ADD(date '2020-12-11',INTERVAL 21 day); --2021-01-01 select DATE_ADD(date '2020-12-11',INTERVAL 1 month);--2021-01-11 select DATE_ADD(date '2020-12-11',INTERVAL 1 week); --2020-12-18 select DATE_ADD(date '2020-12-11',INTERVAL 1 QUARTER);--2021-03-11 select DATE_ADD(date '2020-12-11',INTERVAL 1 year); --2021-12-11 |
|
可以日期直接相减months_between(m,n) | TIMESTAMPDIFF(unit,begin,end); | Mysql:TIMESTAMPDIFF函数返回begin-end的结果,其中begin和end是DATE或DATETIME表达式。 unit参数是确定(end-begin)的结果的单位,表示为整数。 以下是有效单位:MICROSECOND 微秒、 SECOND 秒、 MINUTE 分钟、 HOUR 小时、 DAY 天、 WEEK 周、 MONTH 月份、 QUARTER、 YEAR 年份 Oracle: 支持日期直接相加减。如果是月份差支持函数months_between(m,n) |
Mysql: SELECT TIMESTAMPDIFF(month,date '2020-10-11',date '2020-12-11');----2 SELECT TIMESTAMPDIFF(month,date '2020-10-11',date '2020-12-21');----2 只取整数 Oracle: select date '2020-12-11' - date '2020-10-11' from dual ; ---61 天 select months_between( date'2020-10-11', date'2020-11-11') from dual; -1 select months_between( date'2020-10-21', date'2020-11-11') from dual; -0.67741935483871 可以小数 |
|
LAST_DAY | LAST_DAY | 月末最后一天 LAST_DAY(date) 一致 | Mysql: select LAST_DAY(date '2020-11-11') oracle: select LAST_DAY(date '2020-11-11') from dual; |
|
常用日期写法 | 常用日期写法 | trunc(sysdate) 今天日期, trunc(sysdate,'day') 本周星期日, trunc(sysdate,'month') 本月初, trunc(sysdate,'q') 本季初日期, trunc(sysdate,'year') 本年初日期 round(sysdate) 最近0点日期, round(sysdate,'day') 最近星期日, round(sysdate,'month') 最近月初, round(sysdate,'q') 最近季初日期, round(sysdate,'year') 最近年初日期 add_months(date'2020-11-11', -1) --上月同期 add_months(date'2020-11-11', -3) --上季度同期 add_months(date'2020-11-11', -12) --上年同期 |
#当年第一天: SELECT DATE_SUB(CURDATE(),INTERVAL dayofyear(now())-1 DAY); #当年最后一天: SELECT concat(YEAR(now()),'-12-31'); #当前week的第一天: select date_sub(curdate(),INTERVAL WEEKDAY(curdate()) + 1 DAY); #当前week的最后一天: select date_sub(curdate(),INTERVAL WEEKDAY(curdate()) - 5 DAY); #前一week的第一天: select date_sub(curdate(),INTERVAL WEEKDAY(curdate()) + 8 DAY); #前一week的最后一天: select date_sub(curdate(),INTERVAL WEEKDAY(curdate()) + 2 DAY); #前两week的第一天: select date_sub(curdate(),INTERVAL WEEKDAY(curdate()) + 15 DAY); #前两week的最后一天: select date_sub(curdate(),INTERVAL WEEKDAY(curdate()) + 9 DAY); #当前month的第一天: SELECT concat(date_format(LAST_DAY(now()),'%Y-%m-'),'01'); #当前month的最后一天: SELECT LAST_DAY(now()); #前一month的第一天: SELECT concat(date_format(LAST_DAY(now() - interval 1 month),'%Y-%m-'),'01'); #前一month的最后一天: SELECT LAST_DAY(now() - interval 1 month); #前两month的第一天: SELECT concat(date_format(LAST_DAY(now() - interval 2 month),'%Y-%m-'),'01'); #前两month的最后一天: SELECT LAST_DAY(now() - interval 2 month); #当前quarter的第一天: select concat(date_format(LAST_DAY(MAKEDATE(EXTRACT(YEAR FROM CURDATE()),1) + interval QUARTER(CURDATE())*3-3 month),'%Y-%m-'),'01'); #当前quarter的最后一天: select LAST_DAY(MAKEDATE(EXTRACT(YEAR FROM CURDATE()),1) + interval QUARTER(CURDATE())*3-1 month); #前一quarter的第一天: select concat(date_format(LAST_DAY(MAKEDATE(EXTRACT(YEAR FROM CURDATE()),1) + interval QUARTER(CURDATE())*3-6 month),'%Y-%m-'),'01'); #前一quarter的最后一天: select LAST_DAY(MAKEDATE(EXTRACT(YEAR FROM CURDATE()),1) + interval QUARTER(CURDATE())*3-4 month); #前两quarter的第一天: select concat(date_format(LAST_DAY(MAKEDATE(EXTRACT(YEAR FROM CURDATE()),1) + interval QUARTER(CURDATE())*3-9 month),'%Y-%m-'),'01'); #前两quarter的最后一天: select LAST_DAY(MAKEDATE(EXTRACT(YEAR FROM CURDATE()),1) + interval QUARTER(CURDATE())*3-7 month); |
|
逻辑控制函数 | NVL() | IFNULL()/ if语句/case when 语句 | 处理空字段,并设置默认值 Oracle的NVL函数用法: 语法:NVL(eExpression1, eExpression2) 如果 eExpression1 的计算结果为 null 值,则 NVL( ) 返回 eExpression2。如果 eExpression1 的计算结果不是 null 值,则返回 eExpression1。eExpression1 和 eExpression2 可以是任意一种数据类型。如果 eExpression1 与 eExpression2 的结果皆为 null 值,则 NVL( ) 返回 .NULL.。 返回值类型 字符型、日期型、日期时间型、数值型、货币型、逻辑型或 null 值 Mysql的Ifnull函数用法: IFNULL() 函数用于判断第一个表达式是否为 NULL,如果为 NULL 则返回第二个参数的值,如果不为 NULL 则返回第一个参数的值。 IFNULL() 函数语法格式为: IFNULL(expression, alt_value) |
Mysql: select IFNULL(null,'123') ;---123 select IFNULL('','123') ;----空字符串 Oracle: select nvl('','123') from dual;-----123 select nvl(null,'123') from dual;-----123 在ORACLE中零长度的字符串被视为空值,即: '' = null 所以mysql或者SQLserver数据库转oracle的时候都需要特殊处理。 注意: (1)Null <> Null (2)如果表的某列中含有空值,当该空值要参与计算时,计算的结果依然是空值,一般用NVl来处理空值 (3)null 与 聚合函数 当某列中含有null的记录,使用 min、max,avg等都会把null记录忽略掉,唯有count是一个例外,会把null包含进去。 Mysql里‘’空字符串和Null是有区别的。所以注意什么时候用IFNULL()什么时候用if语句/case when 语句。Ifnull()只能处理null不能处理''。而下面的语句是可以处理的。 SELECT case when a.`name` = '' then '空字符串' when a.`name` is null then 'Null' else a.`name`end from lyy_test_main a ; select IF(a.`name`= '' or a.`name` is null,'空字符串',a.`name`) from lyy_test_main a; |
decode() | if语句/case when 语句 | Mysql 没有decode处理逻辑的函数,他的decode与encode对应的加密解密函数 | ||
case when……then else …… end | case when……then else …… end | 一致 | ||
提交方式 | 手动commit提交 | 自动提交 | 事物提交方式 oracle默认不自动提交,需要用户手动提交。 Mysql默认是自动提交。不支持事物。 Mysql默认自动提交,也就是你提交一个query,它就直接执行,我们可以通过 set autocommit=0 禁止自动提交 set autocommit=1 开启自动提交 |
|
管理相关 | 管理相关 | user_tables\user_columns…… | information_schema数据库表说明: SCHEMATA表:提供了当前mysql实例中所有数据库的信息。是show databases的结果取之此表。 TABLES表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。 COLUMNS表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablename的结果取之此表。 STATISTICS表:提供了关于表索引的信息。是show index from schemaname.tablename的结果取之此表。 USER_PRIVILEGES(用户权限)表:给出了关于全程权限的信息。该信息源自mysql.user授权表。是非标准表。 SCHEMA_PRIVILEGES(方案权限)表:给出了关于方案(数据库)权限的信息。该信息来自mysql.db授权表。是非标准表。 TABLE_PRIVILEGES(表权限)表:给出了关于表权限的信息。该信息源自mysql.tables_priv授权表。是非标准表。 COLUMN_PRIVILEGES(列权限)表:给出了关于列权限的信息。该信息源自mysql.columns_priv授权表。是非标准表。 CHARACTER_SETS(字符集)表:提供了mysql实例可用字符集的信息。是SHOW CHARACTER SET结果集取之此表。 STATISTICS表:查询索引 TABLE_CONSTRAINTS表:描述了存在约束的表。以及表的约束类型。 KEY_COLUMN_USAGE表:描述了具有约束的键列。 VIEWS表:给出了关于数据库中的视图的信息。需要有show views权限,否则无法查看视图信息。 |
|
注释 | 单行注释 -- 多行注释 /%%/ | 单行注释 -- + 空格 或者 # 多行注释 /%%/ | ||