MySQL转Oracle数据库时常见的一些函数转换及一些地方的如何变动

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_40836179/article/details/88863273

1、时间格式

MySQL:

select city_name,DATE_FORMAT(insert_time,'%Y-%m-%d %H:%i:%s') as insert_time from tb_lte_bts

Oracle为:

select city_name,to_char(insert_time, 'yyyy-MM-dd hh24:mi:ss')as insert_time from tb_lte_bts

或者:

select city_name,to_date(insert_time, 'yyyy-MM-dd hh24:mi:ss')as insert_time from tb_lte_bts

到时候,准确的也是要看实际的你的字段存的类型,长度来更改。

2、在MySQL的查询SQL下的 where 条件里,会遇到如下情况

<if test="staStartDate1 != null and staStartDate1.trim().length()>0">
    <![CDATA[ and create_date >= #{staStartDate1} ]]>
</if>
<if test="staEndDate1 != null and staEndDate1.trim().length()>0">
    <![CDATA[ and create_date <  #{staEndDate1} ]]>
</if>

这是对SQL查询的时间范围的判断,在Oracle里我们可以更改为:

<if test="staStartDate1 != null and staStartDate1.trim().length()>0">
    <![CDATA[ and create_date >= to_date(#{staStartDate1},'yyyy-MM-dd hh24:mi:ss') ]]>
</if>
<if test="staEndDate1 != null and staEndDate1.trim().length()>0">
    <![CDATA[ and create_date <  to_date(#{staEndDate1},'yyyy-MM-dd hh24:mi:ss') ]]>
</if>

当然,这个要注意的是,yyyy-MM-dd hh24:mi:ss不是死格式,还是需要按照实际传的内容的颗粒度更改精确到什么时间。

3、拼接函数 concat()

MySQL:

select  
    id,role_name, remark,status
from 
    sys_lte_role
where 
    1=1
<if test="id != null and id.trim().length()>0">
    AND id = #{id}
</if>
<if test="role_name != null and role_name.trim().length()>0">
    AND role_name like concat(concat('%',#{role_name} ),'%')
</if>
<if test="status != null and status.trim().length()>0">
    AND status = #{status}
</if>

Oracle:

select
	id "id",role_name "role_name", remark "remark",status "status"
from 
    sys_lte_role
where 
    1=1
<if test="id != null and id.trim().length()>0">
    AND id = #{id}
</if>
<if test="role_name != null and role_name.trim().length()>0">
    AND role_name like '%' || #{role_name}  || '%'
</if>
<if test="status != null and status.trim().length()>0">
    AND status = #{status}
</if>

4、group by,排序

函数解析:在 MySQL数据库中,我们都知道想怎么排序都是可以的,但是在 Oracle 中可不是,所以,需要一些特殊操作。

MySQL:

SELECT
    a.cell_alarm_type,
    b.factor factor,
    CAST(b.factor_type AS signed) factor_type ,
    COUNT(1) cell_num
FROM
    tb_lte_alarm_cell_net a, tb_lte_alarm_factor b
WHERE
    a.factor_code = b.factor_code 
GROUP BY
    factor, cell_alarm_type

Oracle:

SELECT
    a.cell_alarm_type "cell_alarm_type",b.factor "factor",b.factor_type "factor_type",
    COUNT(*) over(partition by factor, cell_alarm_type) "cell_num"
FROM
    tb_lte_alarm_cell_net a, tb_lte_alarm_factor b
WHERE
    a.factor_code = b.factor_code

这样就可以了,当然,如果说没有 count( ) 那就自己写一个 count( ) ,虽然会增加耗时,但是,莫得办法。

当然,还有如下的解决办法,不过,下面这个就有点难度了,我就混合这一起写了

下面这个比较复杂一些而已。

5、截断小数位 TRUNCATE( X , D ) ,

函数解析:返回数字X,截断到D小数位。

MySQL:

SELECT 
    nbc.city_name,
    nbc.area,
    CONVERT(SUM(nbc.cellRetire),
    DECIMAL(28, 0)) cellRetires,
    CONVERT(SUM(nbc.netRetire),DECIMAL(28, 0)) netRetires ,
    CONCAT(TRUNCATE(sum(nbc.cellRetire) /nbcpi.cellRetireTotal*100,2),'%') cellPi,
    CONCAT(TRUNCATE(sum(nbc.netRetire) /nbcpi.netRetireTotal*100,2),'%') netPi,
    SUM(nbc.cell_num) cell_num,nbcpi.cellRetireTotal,nbcpi.netRetireTotal
FROM 
    tb_lte_alarm_data_nb_count nbc
JOIN 
    tb_lte_alarm_data_nb nbcpi ON nbcpi.city_name=nbc.city_name
WHERE 
    1=1
GROUP BY 
    nbc.city_name,nbc.area

Oracle:

SELECT
    nbc.city_name "city_name",
    nbc.area "area",
    SUM(nbc.cellRetire) over(partition by nbc.city_name, nbc.area) "cellRetires",
    SUM(nbc.netRetire) over(partition by nbc.city_name, nbc.area) "netRetires",
    TRUNC(sum(nbc.cellRetire) over(partition by nbc.city_name, nbc.area) / nbcpi.cellRetireTotal * 100, 2) || '%' "cellPi",
    TRUNC(sum(nbc.netRetire) over(partition by nbc.city_name, nbc.area) / nbcpi.netRetireTotal * 100, 2) || '%' "netPi",
    SUM(nbc.cell_num) over(partition by nbc.city_name, nbc.area) "cell_num",
    nbcpi.cellRetireTotal "cellRetireTotal",
    nbcpi.netRetireTotal "netRetireTotal",
    count(*) over(partition by nbc.city_name, nbc.area) r
FROM 
    tb_lte_alarm_data_nb_count nbc
JOIN 
    tb_lte_alarm_data_nb nbcpi ON nbcpi.city_name=nbc.city_name
WHERE 
    1=1

注:这里要注意的是,SUM( ) 后都要进行排序,这一点要注意,包括 AVG( ) 等等这些函数。

6、NOW( ) + DATE_ADD( )  (注:NOW( ) 和 DATE_ADD( )  一起写了)

函数解析:NOW( ) 获取当前时间戳 

函数解析:DATE_ADD( 日期, INTERVAL 数字 间隔单位 )  在某个日期,加上指定的时间间隔

MySQL:

SELECT
    sum( cur_net_count ) cur_net_count,
    sum( exce_count ) exce_count,
    round( sum( exce_count ) / sum( cur_net_count ) * 100, 2 ) problem_per
FROM
    tb_lte_index_count
WHERE 1=1
    <if test="isTotal != null and isTotal.trim().length()>0">
        AND create_date >= date_add(now(), interval -8 day)
    </if>
    <if test="isCityName != null and isCityName.trim().length()>0">
        AND create_date >= date_add(now(), interval -2 day)
    </if>
    AND create_date <![CDATA[ <= ]]> date_add(now(), interval -1 day)

Oracle:

SELECT
    sum( cur_net_count ) "cur_net_count",
    sum( exce_count ) "exce_count",
    round( sum( exce_count ) / sum( cur_net_count ) * 100, 2 ) "problem_per"
FROM 
    tb_lte_index_count
WHERE
    1=1
    <if test="isTotal != null and isTotal.trim().length()>0">
        AND create_date >= trunc(sysdate)-8
    </if>
    <if test="isCityName != null and isCityName.trim().length()>0">
        AND create_date >= trunc(sysdate)-2
    </if>
    AND create_date <![CDATA[ <= ]]> trunc(sysdate)-1

7、CONVERT( )

函数解析:CONVERT( ) 函数可用来获取一个类型的值,并产生另一个类型的值

MySQL:

SELECT 
    nbc.city_name,
    nbc.area,
    CONVERT(SUM(nbc.cellRetire),
    DECIMAL(28, 0)) cellRetires,
    CONVERT(SUM(nbc.netRetire),DECIMAL(28, 0)) netRetires ,
    CONCAT(TRUNCATE(sum(nbc.cellRetire) /nbcpi.cellRetireTotal*100,2),'%') cellPi,
    CONCAT(TRUNCATE(sum(nbc.netRetire) /nbcpi.netRetireTotal*100,2),'%') netPi,
    SUM(nbc.cell_num) cell_num,nbcpi.cellRetireTotal,nbcpi.netRetireTotal
FROM 
    tb_lte_alarm_data_nb_count nbc
JOIN 
    tb_lte_alarm_data_nb nbcpi ON nbcpi.city_name=nbc.city_name
WHERE 
    1=1
GROUP BY 
    nbc.city_name,nbc.area

Oracle:请不要墨迹,直接删掉它

SELECT
    nbc.city_name "city_name",
    nbc.area "area",
    SUM(nbc.cellRetire) over(partition by nbc.city_name, nbc.area) "cellRetires",
    SUM(nbc.netRetire) over(partition by nbc.city_name, nbc.area) "netRetires",
    TRUNC(sum(nbc.cellRetire) over(partition by nbc.city_name, nbc.area) / nbcpi.cellRetireTotal * 100, 2) || '%' "cellPi",
    TRUNC(sum(nbc.netRetire) over(partition by nbc.city_name, nbc.area) / nbcpi.netRetireTotal * 100, 2) || '%' "netPi",
    SUM(nbc.cell_num) over(partition by nbc.city_name, nbc.area) "cell_num",
    nbcpi.cellRetireTotal "cellRetireTotal",
    nbcpi.netRetireTotal "netRetireTotal",
    count(*) over(partition by nbc.city_name, nbc.area) r
FROM 
    tb_lte_alarm_data_nb_count nbc
JOIN 
    tb_lte_alarm_data_nb nbcpi ON nbcpi.city_name=nbc.city_name
WHERE 
    1=1

8、GROUP_CONCAT( ) 

函数解析:呃~我想偷懒,这个我之前有写过博客,就、、、偷懒了哈~

https://blog.csdn.net/weixin_40836179/article/details/84860514

MySQL:

SELECT
    a.cell_alarm_sub_type,
    GROUP_CONCAT( CONCAT(a.ne_code, '#', a.cell_cde) ) id_str
FROM
    tb_lte_alarm_cell_net_his a, tb_lte_alarm_process_time b

Oracle:

SELECT
    a.cell_alarm_sub_type "cell_alarm_sub_type",
    listagg(a.ne_code || '#' || a.cell_code) within group(order by priority ASC) "id_str"
FROM
    tb_lte_alarm_cell_net_his a, tb_lte_alarm_process_time b

9、IF( ) 判断

MySQL:我想偷懒、、、

IF(LENGTH(IFNULL(d.ne_name_cn,''))=0,1,0)

Oracle:

DECODE(LENGTH(nvl(d.ne_name_cn,'')),0,1,0)

完美~,但是,要注意的是,在后面的原本是" =0 " , 现在需要改为 " ,0 " ,要看仔细了。

还有一种情况,你像这个就需要这样改:

MySQL:

<![CDATA[ IF(gps.Star_Card_state <>'正常' OR gps.GPS_NumberOfSatellites<4,'是','否') AS hidden_danger_Issue ]]>

Oracle:

<![CDATA[ case when gps.Star_Card_state <>'正常' OR gps.GPS_NumberOfSatellites<4 then '是' else '否' end AS hidden_danger_Issue ]]>

10、LENGTH( )

MySQL:

select * from tb_lte_bts where 1=1 and( ISNULL( ne_code ) OR LENGTH( ne_code ) <= 0 )

Oracle:

select * from tb_lte_bts where 1=1 and( LENGTH( NVL( tb_lte_bts, '' ) ) <= 0 )

11、DATE_SUB( ) 

函数解析:从日期减去指定的时间间隔。

正好与 DATE_ADD( ) 相反。

MySQL:

SELECT
    a.*,
    b.*
FROM
    tb_lte_alarm_day_publish a,
    tb_lte_alarm_day_publish b
WHERE
    1=1
    AND b.etl_date = (SELECT DATE_FORMAT(DATE_SUB(NOW(),INTERVAL 1 DAY),'%Y-%m-%d'))

Oracle:

SELECT
    a.*,
    b.*
FROM
    tb_lte_alarm_day_publish a,
    tb_lte_alarm_day_publish b
WHERE
    1=1
    AND b.etl_date = ( SELECT to_char( sysdate - 10, 'yyyymmdd' ) )
    //或者
    AND b.etl_date = ( SELECT trunc( sysdate ) - 10 )

12、取前3名的排列顺序

函数解析:在 MySQL 中,如果你能看到以下一模一样的例子,那就不用想了,它是对所有分组都返回一个数字,然后取某些数据中前三名,说白了,就是想实现 Oracle 中 row_number( ) 函数。

MySQL:

select(
    @i := case  when  @pre_consec_nbr=t1.consec_nbr then @i + 1 else 1 end )  rownum, 
    t1.*,
    (@pre_consec_nbr:= t1.consec_nbr)
from tb_lte_cell t1 
inner join( SELECT  @i := 0, @pre_parent_code:='' ) AS t2

Oracle:

select
    row_number() over( partition by t1.consec_nbr order by t1.consec_nbr) rownum,
    t1.*
from tb_lte_cell t1

13、TIMESTAMPDIFF( HOUR, 开始时间, 结束时间 )

函数解析:求两个时间(开始时间和结束时间)的中间差(HOUR 代表小时)

SELECT 
    count(1) cou_timely,
    etl_date AS etl_date_timely,
    city_name AS city_name_timely
FROM 
    tb_lte_alarm_day_order
WHERE 1=1 
    <![CDATA[ 
        AND process_status=1 
        AND TIMESTAMPDIFF( HOUR, alarm_start_time, update_time ) <= 8 
        AND city_name<>'未知' 
        AND city_name<>''
    ]]>
GROUP BY 
    city_name

Oracle:

SELECT 
    count(1) cou_timely,
    etl_date AS etl_date_timely,
    city_name AS city_name_timely
FROM 
    tb_lte_alarm_day_order
WHERE 1=1 
    <![CDATA[ 
        AND process_status=1 
        AND ROUND( TO_NUMBER( update_time - alarm_start_time ) * 24 ) <= 8
        AND city_name<>'未知' 
        AND city_name<>''
    ]]>
GROUP BY 
    city_name

14、其他的就是一些注意事项,

1、比如:针对于成熟的项目,进行数据库迁移时,需要对所有的数据字段起别名,因为,如果你是改程序中的字段都改为大写,成本较高,不建议改程序中的字段,所以,建议针对 select 语句的字段,都起一个别名,并用英语双引号引起来,这样成本较低,省时省力。

2、针对如下语句

CASE 字段 WHEN 1 THEN '输出' END 字段名称

这类字段,需要改成如下:

CASE 字段 WHEN '1' THEN '输出' END AS '字段名称'

要不然会报应该是 CHAR 实际得到的 INT 或者别的类似的问题。

3、对于在时间查询的时候,我们会用到 <= 或者 >= 这些东西,这时我们需要对它进行一些修改

SELECT
    *
FROM 
    tb_lte_index_count
WHERE
    1=1
    AND create_date <![CDATA[ <= ]]> trunc(sysdate)-1
    //或者
    <![CDATA[ AND create_date <= trunc(sysdate)-1 ]]>

暂时就有这么多以后再有了我再加吧,

大家要是有遇见什么别的函数了,可以写到评论区,

欢迎大家留言。

完(没得事,我就是想弄成这个色 ... ...)

猜你喜欢

转载自blog.csdn.net/weixin_40836179/article/details/88863273