Oracle遷移MySQL 8特殊SQL處理

  • 遞歸查詢

在Oracle中創建一個表html

create table nayi_180328_connect_test(
	dept_id varchar2(50), 
	parent_id varchar2(50), 
	dept_name varchar2(100), 
	dept_rank varchar2(2000), 
	val number);

插入語句mysql

insert into nayi_180328_connect_test
	select 'root', '', '全國', '', 0 from dual
	union all
	select 'root_1', 'root', '北京市', '', 2000 from dual
	union all
	select 'ln_root', 'root', '遼寧省', '', 200 from dual
	union all
	select 'ln_ys', 'ln_root', '遼寧省瀋陽市', '', 1000 from dual
	union all
	select 'ln_sy_hp', 'ln_ys', '遼寧省瀋陽和平區', '', 500 from dual
	union all
	select 'ln_ys_dd', 'ln_ys', '遼寧省瀋陽大東區', '', 600 from dual
	union all
	select 'jl_root', 'root', '吉林省', '', 0 from dual
	union all
	select 'jl_jl', 'jl_root', '吉林省吉林市', '', 200 from dual
	union all
	select 'jl_cc', 'jl_root', '吉林省長春市', '', 500 from dual
	;

Oracle的遞歸查詢語句以下sql

select t1.*,CONNECT_BY_ROOT(dept_name) root_name
	  from nayi_180328_connect_test t1
	 where 1=1
	 connect by prior t1.dept_id = t1.parent_id
	 start with t1.dept_id = 'root'
	;

結果以下oracle

遷移MySQL 8,建表以下app

create table nayi_180328_connect_test(
	dept_id varchar(50), 
	parent_id varchar(50), 
	dept_name varchar(100), 
	dept_rank varchar(2000), 
	val int,
	PRIMARY key	(dept_id)
	)

插入語句與Oracle相同函數

insert into nayi_180328_connect_test
	select 'root', '', '全國', '', 0 from dual
	union all
	select 'root_1', 'root', '北京市', '', 2000 from dual
	union all
	select 'ln_root', 'root', '遼寧省', '', 200 from dual
	union all
	select 'ln_ys', 'ln_root', '遼寧省瀋陽市', '', 1000 from dual
	union all
	select 'ln_sy_hp', 'ln_ys', '遼寧省瀋陽和平區', '', 500 from dual
	union all
	select 'ln_ys_dd', 'ln_ys', '遼寧省瀋陽大東區', '', 600 from dual
	union all
	select 'jl_root', 'root', '吉林省', '', 0 from dual
	union all
	select 'jl_jl', 'jl_root', '吉林省吉林市', '', 200 from dual
	union all
	select 'jl_cc', 'jl_root', '吉林省長春市', '', 500 from dual

MySQL 8遞歸查詢語句以下spa

with recursive t1(dept_id,parent_id,dept_name,dept_rank,val,root_name,rownum, order_str) as (
			select t0.*,t0.dept_name,@rownum := 1 rn, cast(@rownum as char) sdfsf from nayi_180328_connect_test t0 where t0.dept_id='root'
			union all
			select t2.*,t1.root_name,@rownum := @rownum + 1 rn, concat(t1.order_str, '-', @rownum) st  from nayi_180328_connect_test t2,t1
			where t2.parent_id = t1.dept_id
	)
	select * from t1 order by order_str

結果以下3d

  • 日期轉換字符串

Oracle中code

select to_char(sysdate,'yyyy-mm-dd') from dual

結果orm

2020-05-07

MySQL 8中

select date_format(now(),'%Y-%m-%d') from dual

結果

2020-05-07

  • 字符串轉換日期

Oracle中

select to_date('2020-01-01','yyyy-mm-dd') from dual

結果

2020-01-01 00:00:00

MySQL 8中

select str_to_date('2020-01-01','%Y-%m-%d %h:%i:%s') from dual

結果

2020-01-01 00:00:00

  • 判斷爲空,用其餘值代替

Oracle中

select nvl(parent_id,'boot') from nayi_180328_connect_test where dept_id='root'

結果

boot

MySQL 8中

select ifnull(parent_id,'boot') from nayi_180328_connect_test where dept_id='root'

結果

boot

  • 條件判斷取值

Oracle中

select decode(parent_id,null,'全國','root','省市','地區') from nayi_180328_connect_test

結果

MySQL 8中

select case when parent_id is null then '全國' when parent_id='root' then '省市' else '地區' end from nayi_180328_connect_test

結果

  • 聚合字段拼接

在Oracle中

WITH TEMP AS(  
SELECT 'CHINA' NATION ,'GUANGZHOU' CITY FROM DUAL UNION ALL  
SELECT 'CHINA' NATION ,'SHANGHAI' CITY FROM DUAL UNION ALL  
SELECT 'CHINA' NATION ,'BEIJING' CITY FROM DUAL UNION ALL  
SELECT 'USA' NATION ,'NEW YORK' CITY FROM DUAL UNION ALL  
SELECT 'USA' NATION ,'BOSTOM' CITY FROM DUAL UNION ALL  
SELECT 'JAPAN' NATION ,'TOKYO' CITY FROM DUAL   
)  
SELECT 
NATION,LISTAGG(CITY,',') WITHIN GROUP (ORDER BY CITY)  AS CITIES
FROM TEMP  
GROUP BY NATION

結果

在MySQL 8中

WITH TEMP AS(  
SELECT 'CHINA' NATION ,'GUANGZHOU' CITY FROM DUAL UNION ALL  
SELECT 'CHINA' NATION ,'SHANGHAI' CITY FROM DUAL UNION ALL  
SELECT 'CHINA' NATION ,'BEIJING' CITY FROM DUAL UNION ALL  
SELECT 'USA' NATION ,'NEW YORK' CITY FROM DUAL UNION ALL  
SELECT 'USA' NATION ,'BOSTOM' CITY FROM DUAL UNION ALL  
SELECT 'JAPAN' NATION ,'TOKYO' CITY FROM DUAL   
)  
SELECT 
NATION,GROUP_CONCAT(city order by city) cities
FROM TEMP  
GROUP BY NATION

結果

  • 截取字符串

在Oracle中

select substr('HelloWorld',0,3) value from dual;
select substr('HelloWorld',1,3) value from dual;

以上執行結果相同

Hel

在MySQL 8中

select substr('HelloWorld',1,3) value from dual;

在MySQL中,substr()的首索引不能爲0

結果

Hel

  • 數字格式化字符串

在Oracle中

select to_char(12345678.657,'999,999,999,999.99')  from dual;

結果

12,345,678.66

在MySQL 8中

select format(12345678.657,2)  from dual;

結果

12,345,678.66

  • 跨庫查詢

在Oracle中

select 字段名 from 表名@庫名

在MySQL 8中

select 字段名 from 庫名.表名

  • 拼接字符串

在Oracle中

select 'ABC' || 'EFG' from dual

結果

ABCEFG

在MySQL 8中

select concat('ABC','EFG') from dual

結果

ABCEFG

  • 表分區

在Oracle中

咱們先建立兩個表空間

create tablespace CUS_TS01 datafile '/home/oracle/app/oracle/oradata/helowin/cus01.dbf' size 20m;
create tablespace CUS_TS02 datafile '/home/oracle/app/oracle/oradata/helowin/cus02.dbf' size 20m;

此時查詢表空間

select * from dba_tablespaces;

結果

咱們能夠看到最後兩個表空間是咱們剛生成的

CREATE TABLE CUSTOMER
(
    CUSTOMER_ID NUMBER NOT NULL PRIMARY KEY,
    FIRST_NAME  VARCHAR2(30) NOT NULL,
    LAST_NAME   VARCHAR2(30) NOT NULL,
    PHONE        VARCHAR2(15) NOT NULL,
    EMAIL        VARCHAR2(80),
    STATUS       CHAR(1)
)
PARTITION BY RANGE (CUSTOMER_ID)
(
    PARTITION CUS_PART1 VALUES LESS THAN (100000) TABLESPACE CUS_TS01,
    PARTITION CUS_PART2 VALUES LESS THAN (200000) TABLESPACE CUS_TS02
)

咱們建立一個表,並生成兩個表分區CUS_PART1,CUS_PART2.關於分區的分類能夠參考https://www.cnblogs.com/wnlja/p/3979684.html

插入一條數據

insert into customer values (1,'Li','xiaoping','123456987','lixiaoping@123.com','1')

因爲該分區是以數據的數目來進行分區的,前10W行在第一個分區,後10W行在第二個分區,因此咱們按分區來進行查詢時,只能在第一個分區查到該數據,而第二個分區是沒有的

select * from customer partition(CUS_PART1)

select * from customer partition(CUS_PART2)

在MySQL 8中

建立一樣的表,一樣的分區,關於MySQL表分區的分類能夠參考https://www.cnblogs.com/zhouguowei/p/9360136.html

CREATE TABLE CUSTOMER
(
    CUSTOMER_ID int NOT NULL,
    FIRST_NAME  VARCHAR(30) NOT NULL,
    LAST_NAME   VARCHAR(30) NOT NULL,
    PHONE        VARCHAR(15) NOT NULL,
    EMAIL        VARCHAR(80),
    STATUS       CHAR(1),
		primary key (CUSTOMER_ID)
)
PARTITION BY RANGE (CUSTOMER_ID)
(
    PARTITION CUS_PART1 VALUES LESS THAN (100000),
    PARTITION CUS_PART2 VALUES LESS THAN (200000)
)

插入一樣的數據

insert into CUSTOMER values (1,'Li','xiaoping','123456987','lixiaoping@123.com','1')

進行分區查詢

select * from CUSTOMER partition(CUS_PART1)

select * from CUSTOMER partition(CUS_PART2)

  • 日期相減

在Oracle中

不少人喜歡用

trunc(日期1)-trunc(日期2)

由於trunc(日期)能夠去掉時間部分,好比

select sysdate from dual

結果

2020-05-14 09:59:27

select trunc(sysdate) from dual

結果

2020-05-14 00:00:00

注:trunc(日期,'dd')與trunc(日期)意義相同

select trunc(sysdate ,'dd') from dual ;

結果

2020-05-15 00:00:00

在MySQL 8中

mysql中沒有trunc函數,直接用

日期1-日期2

但若是日期帶了時間部分,好比

select now() from dual

結果

2020-05-14 02:15:14

若是此時用帶時間的日期相減會出錯,能夠用以下方式處理

select str_to_date(now(),'%Y-%m-%d')-str_to_date('2020-05-01','%Y-%m-%d') from dual

結果

13

爲了保險起見,能夠將Oracle中的trunc(日期)轉換成str_to_date(日期,'%Y-%m-%d')

  • 獲取當前年份的第一天

在Oracle中

select TRUNC(SYSDATE, 'yyyy') from dual

結果

2020-01-01 00:00:00

在MySQL 8中

SELECT DATE_SUB(CURDATE(),INTERVAL dayofyear(now())-1 DAY) from dual

結果

2020-01-01

date_sub() 從日期減去指定的時間間隔。

格式:

DATE_SUB(date,INTERVAL expr type)

CURDATE() 函數返回當前的日期,不帶時間

select curdate() from dual

結果

2020-05-14

DAYOFYEAR() 函數返回指定日期在一年中的位置

select dayofyear('2020-05-13') from dual

結果

134

DATE_SUB()函數的type爲如下類型

Type值
MICROSECOND
SECOND
MINUTE
HOUR
DAY
WEEK
MONTH
QUARTER
YEAR
SECOND_MICROSECOND
MINUTE_MICROSECOND
MINUTE_SECOND
HOUR_MICROSECOND
HOUR_SECOND
HOUR_MINUTE
DAY_MICROSECOND
DAY_SECOND
DAY_MINUTE
DAY_HOUR
YEAR_MONTH
  • 幾個月以後(以前)的某天

在Oracle中

select ADD_MONTHS (to_date('2020-01-01','yyyy-mm-dd') , 3) from dual union all
select ADD_MONTHS (to_date('2020-01-01','yyyy-mm-dd') , -3) from dual

結果

2020-04-01 00:00:00

2019-10-01 00:00:00

在MySQL 8中

SELECT ADDDATE('2020-01-01', INTERVAL 3 MONTH) from dual union all
SELECT ADDDATE('2020-01-01', INTERVAL -3 MONTH) from dual

結果

2020-04-01

2019-10-01

相關文章
相關標籤/搜索