Postgre與Oracle編寫SQL的區別與轉換方法


1.instr函數可以用like替換

也可以用 POSITION ('試油' in T1.WELLTESTMETHOD)>0替換

2.decode可以用case when 2 then 2 when 1 then -1替換

SELECT
M.DESIGN_ID,
MAX( DECODE( M.AUDIT_CODE, 2, 2, 1,- 1, 0, 0 ) ) AUDIT_CODE
FROM
PC_BUILD_DAILY_REPORT_DAY M
WHERE
to_date ( m.control_date, 'yyyy-mm-dd' ) = to_date ( '2019-05-21', 'yyyy-mm-dd' )
GROUP BY
M.DESIGN_ID

 

SELECT
A.design_id,
MAX(
CASE A.AUDIT_CODE
WHEN '2' THEN '2'
WHEN '1' THEN '-1'
WHEN '0' THEN '0'
END) AS AUDIT_CODE
FROM PC_BUILD_DAILY_REPORT_DAY A
WHERE
to_date ( A.control_date, 'yyyy-mm-dd' ) = to_date ( '2019-05-21', 'yyyy-mm-dd' )
GROUP BY
A.DESIGN_ID

3.SUBSTR 截取字符串的開始位置必須為1 例如截取aaaaa的四位 SUBSTR ('aaaaa',1,4) 若為SUBSTR ('aaaaa',0,4) 則無效

4.PostgreSQL中不需要dual虛擬表 select語句可以沒有from

5.類似於select *from(select...) from里面的子查詢必須要起別名,多層嵌套一樣都要起別名

select *from(select *from(select...) as A)as B

6.postgre中沒有trunc、addmonthslastday函數可以用date_trunc、interval替代(已經編寫了f_add_months f_last_day函數可用)

例子:

求日期該年第一天
trunc(TO_DATE('20190714', 'yyyymmdd'),'yyyy')
date_trunc('year',TO_DATE('20190714', 'yyyymmdd'))

求日期該年最后一天 兩種方式替換(第二種比較好)
last_day(add_months(trunc(TO_DATE('20190714', 'yyyymmdd'),'y'),11))
date_trunc('day',(date_trunc('year',TO_DATE('20190714', 'yyyymmdd'))+ interval '11 month')+interval '30 day')
(date_trunc('MONTH',date_trunc('year',TO_DATE('2019-07-14', 'yyyy-mm-dd'))+ interval '11 month') + INTERVAL '1 MONTH - 1 day')
求日期該月第一天
TRUNC(TO_DATE('20190414', 'yyyymmdd'),'mm')
TRUNC(ADD_MONTHS(LAST_DAY(TO_DATE('20190414', 'yyyymmdd')),-1)) + 1
date_trunc('MONTH',(date_trunc('MONTH',to_date('2019-07-09','yyyy-mm-dd')) - INTERVAL '1 MONTH')+ INTERVAL '1 MONTH')


詳細介紹見https://blog.csdn.net/liguangxianbin/article/details/80166574

7.postgre中沒有nvl函數,可以用coalesce函數替代

nvl(collect_result,0) as collect_result
coalesce(collect_result,0) as collect_result

8.字符串去掉空格

oracle
Select LTRIM(' sql_in_a_nutshell'),
Select RTRIM('sql_in_a_nutshell '),
TRIM(' sql_in_a_nutshell ')
FROM dual;


PostgreSQL
Select TRIM(LEADING FROM ' sql_in_a_nutshell'),
TRIM(TRAILING FROM 'sql_in_a_nutshell '),
TRIM(BOTH FROM ' sql_in_a_nutshell ');

9.上面清除空格相反的操作,添加空格

oracle
Select LPAD(('sql', 5, ' '),
RPAD(('sql', 5, ' ')
FROM dual;


PostgreSQL
Select LPAD('sql', 5, ' '),
LPAD('sql', 2, ' '),
RPAD('sql', 5, ' '),
RPAD('sql', 2, ' '),;
//結果為 ' sql' 'sq' 'sql ' 'ql'

10.字符串替換

oracle
Select
REPLACE('wabbit_season','it_','it_hunting_')
FROM dual;


PostgreSQL
Select TRANSLATE('wabbit_season','it_','it_hunting_');
Select replace('wabbit_season','it_','it_hunting_');

 

 

11.NULLIF(expression1, expression2) 如果 expression1 等於 expression2則返回 NULL,如果expression1的值為null,也返回NULL

oracle
Select DECODE(foo,'Wabbits!',NULL)
FROM dual;


PostgreSQL
Select NULLIF(foo, 'Wabbits!');

12.postgre中沒有nvl2函數,可以用case when is not null then 2 else 1替換

nvl2(name, '有人', '無人')

when name is not null then '有人' else '無人' end

13 REGEXP_SUBSTR可以替換為substring (匹配正則表達式)

REGEXP_SUBSTR(ST.STRAT_UNIT_NAME,'[^'|| UNISTR('\4e00') ||'-'||UNISTR('\9fa5') || ']',1,1)
SELECT substring(ST.STRAT_UNIT_NAME from '[^\u4e00-\u9fa5]')

 

 

14 postgre函數學習手冊https://blog.csdn.net/zdq0394123/article/details/8227567

15 FNSPLIT 可以用regexpsplittotable替換(列轉行)

SELECT split_part('哈-哈哈哈', '哈', 2) //結果 -
SELECT substring('你好-哈哈' from '([\u3007\u3400-\u4DB5\u4E00-\u9FCB\uF900-\uFA2D]+-)')//結果 你好-
SELECT a.string_to_array[2] from (SELECT string_to_array ('a,b,b',',')) as a //結果b
SELECT split_part('accb','c',2) //無結果
SELECT regexp_split_to_table('a,b,b',',')//結果a b b集合

 

 

16(行轉列)

PIVOT(MAX(BTM_DEPTH) BTM_DEPTH,(MAX(BTM_DEPTH - TOP_DEPTH)) THICKNESS, MAX(OIL_GAS_POSITION) OIL_GAS_POSITION, MAX(DIP_ANGLE) DIP_ANGLE
FOR PHASE IN('設計' DESIGN, '實際' ACTUAL))


max( CASE WHEN PHASE = '設計' THEN BTM_DEPTH ELSE 0 END ) AS DESIGN_BTM_DEPTH,
max( CASE WHEN PHASE = '實際' THEN BTM_DEPTH ELSE 0 END ) AS ACTUAL_BTM_DEPTH,
max( CASE WHEN PHASE = '設計' THEN BTM_DEPTH - TOP_DEPTH ELSE 0 END ) AS DESIGN_THICKNESS,
max( CASE WHEN PHASE = '實際' THEN BTM_DEPTH - TOP_DEPTH ELSE 0 END ) AS ACTUAL_THICKNESS,
max( CASE WHEN PHASE = '設計' THEN OIL_GAS_POSITION ELSE '' END ) AS DESIGN_OIL_GAS_POSITION,
max( CASE WHEN PHASE = '實際' THEN OIL_GAS_POSITION ELSE '' END ) AS ACTUAL_OIL_GAS_POSITION,
max( CASE WHEN PHASE = '設計' THEN DIP_ANGLE ELSE 0 END ) AS DESIGN_DIP_ANGLE,
max( CASE WHEN PHASE = '實際' THEN DIP_ANGLE ELSE 0 END ) AS ACTUAL_DIP_ANGLE

17 postgre對於數據類型的要求十分嚴格,並且沒有自動轉換格式,而oracle對於數據類型要求不是十分嚴格

例如用||拼接字符串的時候 'aaa'||123||'bbb' 這種就會報錯(oracle不會報錯,正常運行) 需要改為 'aaa'||to_char(123,'99999999999')||'bbb' 才能拼接 ,

需要編寫者自行匹配正確的數據格式,如果格式不相符,則需要用to_char(字段,'999999999999')to_number(字段,'9999999999999999') cast(字段 as varchar)  cast(字段 as integer)

PS:

對於to_char 9的數量沒有限制,盡量多些,不然會丟失結果,

to_char(123,'9') 結果為 ' #';

to_char(123,'99') 結果為 ' ##';

to_char(123,'999') 結果為 ' 123'

to_char(123,'9999') 結果為 ' 123'

隨着9的增加 123前面的空格增多,但並不影響計算

對於to_number 9的數量沒有限制,盡量多些,不然會丟失位數,

to_number('123','9') 結果為 1;

to_number('123','99') 結果為 12;

to_number(123,'999') 結果為 123

to_char(123,'9999') 結果為 123 隨着9的增加 結果始終是123

 

18 賊實用的generate_series函數

函數

參數類型

返回類型

描述

generate_series(start, stop)

int 或 bigint

setof int 或 setof bigint(與參數類型相同)

生成一個數值序列,從start 到 stop,步進為一

generate_series(start, stop, step)

int 或 bigint

setof int 或 setof bigint(與參數類型相同)

生成一個數值序列,從start 到 stop,步進為step

generate_series(start, stop, step_interval)

timestamp or timestamp with time zone

timestamp 或 timestamp with time zone(same as argument type)

生成一個數值序列,從start 到 stop,步進為step

SELECT generate_series(1,5,2)

結果

1

3

5

select date(zz) as t from generate_series(date_trunc('month',to_date('201505','yyyymm')), date_trunc('month',to_date('201507','yyyymm')),'1 month') as zz;

結果

2015-05-01

2015-06-01

2015-07-01

19 新增fn_get_month_days函數,獲取當月天數

例子:

select fn_get_month_days('201912')

結果  31

20 替代Oracle中ALL_TAB_COLUMNSALL_TABLES

ALL_TAB_COLUMNS:

SELECT
col_description ( A.attrelid, A.attnum ) AS COMMENT,
format_type ( A.atttypid, A.atttypmod ) AS TYPE,
A.attname AS NAME,
A.attnotnull AS NOTNULL
FROM
pg_class AS C,
pg_attribute AS A
WHERE
C.relname = 'cd_well'
AND A.attrelid = C.oid
AND A.attnum > 0

ALL_TABLES:

SELECT
relname AS tabname,
CAST ( obj_description ( relfilenode, 'pg_class' ) AS VARCHAR ) AS COMMENT
FROM
pg_class C
WHERE
relkind = 'r'
AND relname NOT LIKE'pg_%'
AND relname NOT LIKE'sql_%'
ORDER BY
relname

21 ‘a’ || null=?

Oracle中 ‘a’ || null = ‘a’

Postgre中 ‘a’ || null = null


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM