MySQL和Oracle里面SQL转换


oracle环境有关sql的注意事项

 

比较特殊的:

1. 原有 MySQL字段设置为 not null default ''

原因: ORACLE 数据库 不允许存空字符串, 认为它跟null是一样的 修改: 这种情况下, 在xml中, 我们暂时的处理办法是在xml中修改原先插入的空字符串变为固定格式的字符串, 格式为"NULL_大写的列名或者列名简称"

根据观察, 存为空的情况, 可能是指, 这些数据是 作为一种默认配置的设定 目前有修改的是 a. account_performance_info_daily表中的account_type字段 => 'NULL_TYPE' b. life_cycle_saas_attachment 表中的tenant字段 => 'NULL_TENANT'

具体业务逻辑碰到冲突的地方需要进行相应更改, 一般是在select以及不同的 type case 判断上

2. 有部分的sql 并没有写在xml中

这种情况可能是遇到了sql 语句 是: a. 存在了数据库表中 例: select TABLE_NAME as tableName, DELETE_SQL as deleteSql from custom_account_data_tables b. 代码里面动态拼出来的 customSql c. 根据model 上的注解, 通过反射, 动态拼出来的 例: DbSearchUtil

如果碰到不适配的语句时, 一般是在OracleUtil类中进行相关修改的

3. 同时删除2表的操作,进行了修改,变成了 2个删除语句.

例: accountMapper.deleteBenchMarkById(benchMarkIds); accountMapper.deleteBecnchMarkWeightById(benchMarkIds);

 

4. 不同的schema 在注入 DataSource的时候,进行一个设置.

hikariConfig.setConnectionInitSql("ALTER SESSION SET CURRENT_SCHEMA = " + schema);

有关语法的:

1. 在insert中有忽略 唯一索引检查的操作, 语法与mysql 不同

例: <insert id="insertPermissions" parameterType="java.util.List"> insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(acl_entry(user, object_id, data_id)) */ into acl_entry("USER", object_id, data_id) <foreach collection="list" item="element" index="index" separator="union all"> ( select #{element.user, jdbcType = VARCHAR}, #{element.objectId, jdbcType = INTEGER}, #{element.dataId, jdbcType = VARCHAR} from dual) </foreach> </insert>

关于jdbcType根据现有的数据库设定来看, 与java类型的设定建议统一如下:

与数字相关的数据库一般使用NUMBER类型, jdbcType统一使用 NUMERIC

Java Type jdbcType
String VARCHAR
Boolean NUMERIC
Integer NUMERIC
Long NUMERIC
Double NUMERIC
Date DATE
DateTime TIMESTAMP
   

更多设置可以参考 http://www.mybatis.org/mybatis-3/apidocs/reference/org/apache/ibatis/type/JdbcType.html

 

2. SELECT * FROM ACCOUNT WHERE ID IN (1,2,3)

上述in的参数个数, Oracle 上限是1000个, 目前的处理办法是在OracleUtil中分批查询然后合并结果

3. Oracle 是大小写不敏感的, 如果不使用别名, 默认返回的列名会是全部大写

 

4. 列名显式引用 需要使用双引号

常量VARCHAR使用单引号, 使用 0 或者 1 查询, 映射到Boolean字段上, 使用 as 别名的时候, 在表名后面一定 不要 使用, 在列名后面 可以 使用, 在where条件中, 使用原始列名 查询 如果列名是关键词,那么需要使用双引号 显式使用 例: select "LEVEL" as "level" from life_cycle_saas_event_type a where a."LEVEL" = '母基金'

5. 根据条件进行删除的语句, delete 加上 join条件

例: <delete id="deleteRequirement"> delete from PRE_REQUIREMENT where rowid in ( select a.rowid from PRE_REQUIREMENT a left join pre_requirement_trace b on a.channel = b.channel where a.id = #{id} ) </delete>

6. 插入与更新操作中, 如果值可能为null, 需要显式指定jdbcType, 不然会报错. 例子见下一条.

 

7. 与mysql的replace into 语法相对应的写法如下

 

<insert id="moveInternalAccountsToDel" parameterType="com.datayes.mom.instance.attribution.AccountDel"> <!-- replace into account_del(ACCOUNT_ID, ACCOUNT_DATA, EXTERNAL_SOURCE) values <foreach collection="list" item="record" separator=","> (#{record.accountID}, \#{record.accountData}, \#{record.externalSource}) </foreach> Attention: Columns referenced in the ON Clause cannot be updated FOR ORACLE --> MERGE INTO account_del A USING ( <foreach collection="list" item="record" separator=" union all " index="index"> select #{record.accountID, jdbcType=VARCHAR} as accountID, #{record.accountData, jdbcType=VARCHAR} as accountData, #{record.externalSource, jdbcType=VARCHAR} as externalSource from dual </foreach> ) B ON (A.ACCOUNT_ID=B.accountID) WHEN MATCHED THEN UPDATE set A.ACCOUNT_DATA=B.accountData, A.EXTERNAL_SOURCE=B.externalSource WHEN NOT MATCHED THEN INSERT (ACCOUNT_ID, ACCOUNT_DATA, EXTERNAL_SOURCE) VALUES(B.accountID,B.accountData,B.externalSource)

</insert>

8. Oracle中的 分页查询参考下面的例子, 查询第2到11条数据

SELECT * FROM ACCOUNT OFFSET 1 ROWS FETCH NEXT 10 ROWS ONLY

9. 虽然在客户端中可以使用分号';'作为结尾, 但是在xml中使用分号将导致 sql 执行报错

 

10. 一些不同的函数

a. 获取今天的日期

SELECT TRUNC(sysdate, 'DD') FROM dual

b. 连接多个字符串

result.userName like '%' || #{keyword} || '%'
c. 映射到boolean的例子

 

d. regexp 正则匹配,对应 REGEXP_LIKE

REGEXP_LIKE(查询的字段,正则表达式)

 

11.插入时返回主键id

原语法


<insert id="insert" useGeneratedKeys="true" keyColumn="ID" keyProperty="id">
  INSERT INTO xt_account_rule_info
  (ACCOUNT_ID, ACCOUNT_CODE, ACCOUNT_NAME, ACCOUNT_SET_ID, ACCOUNT_SHEET_NAME, ACCOUNT_CELL, DATE_START_CELL,
  UNIT_VALUE_START_CELL, ADJUST_VALUE_START_CELL, ACCUMULATE_VALUE_START_CELL)
  VALUES
  (#{accountId}, #{accountCode}, #{accountName}, #{accountSetId}, #{accountSheetName}, #{accountCell}, #{dateStartCell},
  #{unitValueStartCell}, #{adjustValueStartCell}, #{accumulateValueStartCell})
</insert>

由于Oracle是不支持自动生成主键的,不像Sql或者Mysql能自动生成。所以 需要将 useGeneratedKeys 设置为false,并添加selectKey标签,查询对应的自增序列id并返回,如下:

 

<insert id="insert" useGeneratedKeys="false" keyColumn="ID" keyProperty="id">
      <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
          SELECT
          get_seq_curr(sequence_name)
          FROM
          user_tab_identity_cols
          WHERE
          table_name = UPPER('xt_account_rule_info')
      </selectKey>
      INSERT INTO xt_account_rule_info
      (ACCOUNT_ID, ACCOUNT_CODE, ACCOUNT_NAME, ACCOUNT_SET_ID, ACCOUNT_SHEET_NAME, ACCOUNT_CELL, DATE_START_CELL,
      UNIT_VALUE_START_CELL, ADJUST_VALUE_START_CELL, ACCUMULATE_VALUE_START_CELL)
      VALUES
      (#{accountId,jdbcType=VARCHAR}, #{accountCode,jdbcType=VARCHAR}, #{accountName,jdbcType=VARCHAR}, #{accountSetId}, #{accountSheetName,jdbcType=VARCHAR}, #{accountCell,jdbcType=VARCHAR}, #{dateStartCell,jdbcType=VARCHAR},
      #{unitValueStartCell,jdbcType=VARCHAR}, #{adjustValueStartCell,jdbcType=VARCHAR}, #{accumulateValueStartCell,jdbcType=VARCHAR})
  </insert>  

 

 

 

12 不支持left 与 right函数

可以通过substr函数来进行替代

substr(字符串,截取开始位置,截取长度)

截取开始位置 = 负数时,表示截取的开始位置为字符串右端向左数第 截取长度 个字符

例如:

substr(str,0,2),等价于 left(str,2)

substr(str,-2,2),等价于 right(str,2)

替换公式如下:

right(str,len) -> substr(str,-len,len)

left(str,len) -> substr(str,0,len)

 

特别的,对于日期类型的截取,在mysql中可以直接使用left或者right函数进行操作,在oracle中,需要将对应的日期字段转换为标准的字符串内容后,再进行截取,比如:

在mysql中:

select left(curdate(),7) 可以得到:2022-02

在oracle中要使用substr替换

select substr(to_char(sysdate,'yyyy-MM-dd'),0,7) from dual;

13 char

对于char类型的字段,如果字段值实际长度小于字段设定长度,虽然肉眼看上去是没有空格的,但是实际上会在尾部补充空格,所以查询的时候,需要将字段trim之后或者将查询条件补充空格后进行查询。

不过一般来说,字段之所以定义为char类型,就是因为对应字段实际值会是定长的,所以一般也不需要额外的修改。对于一些特别的情况,可以按照上述方案,将查询字段添加trim函数后进行比较:TRIM(字段)=查询值

 

14 位运算

Oracle中只有位余运算:BITAND,表示返回两个数值型数值在按位进行 AND 运算后的结果。

语法:BITAND(nExpression1, nExpression2) BITAND将 nExpression1 的每一位同 nExpression2 的相应位进行比较。如果 nExpression1 和 nExpression2 的位都是 1,相应的结果位就是 1;否则相应的结果位是 0。

与:bitand,例如: bitand(7,1) 等价于 7 & 1

 

15 datediff函数

在oracle中没有datediff()函数 可以用以下方法在oracle中实现该函数的功能:

天:
ROUND(TO_NUMBER(END_DATE - START_DATE))
小时:
ROUND(TO_NUMBER(END_DATE - START_DATE) * 24)
分钟:
ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60)
秒:
ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60 * 60)
毫秒:
ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60 * 60 * 60)
getFundClose

16 CONCAT 函数

在mysql中 CONCAT函数可以拼接任意数量的参数

在oracle中,CONCAT函数仅接收两个参数的拼接,可用 || 替换

例如:

在mysql中,使用concat(1,2,3,4,5)

在oracle中,可替换为 1 || 2 || 3 || 4 || 5

 

 

17 oracle字段拼接过程中以0开头的小数,开头的0消失

为何小数点前0会省略,是因为oracle数据库中存在一个隐形类型转换,在拼接的过程中小数自动转成字符类型,相当于调用了to_char函数,所以丢失小数点前面的0

这里操作就是把数值类型转换为字符型,即加上to_char(字段,’fm9999999999999990.00’)

其中9代表如果存在数字则显示数字,不存在则显示空格; 0代表如果存在数字则显示数字,不存在则显示0,即占位符; fm代表删除如果是因9带来的空格,则删除。

18 时间差函数:timestampdiff

语法:timestampdiff(interval, datetime1,datetime2)

结果:返回(时间2-时间1)的时间差,结果单位由interval参数给出。

 

单位 MySQL(UNIT) oracle
毫秒   ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60 * 60 * 60)
second ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60 * 60)
分钟 minute ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60)
小时 hour ROUND(TO_NUMBER(END_DATE - START_DATE) * 24)
day ROUND(TO_NUMBER(END_DATE - START_DATE))
week  
month trunc(months_between(END_DATE,START_DATE))
quarter  
year trunc(months_between(END_DATE,START_DATE)/12)

19 中文排序问题

mysql 可以用过转换编码,达到使用中文拼音首字母排序的功能

order by convert ( 字段名 using gbk ) asc

在oracle中 可以使用

order by nlssort(字段名,'NLS_SORT=SCHINESE_PINYIN_M') asc

 

20 QUARTER() 函数,获取日期对应的季度

在mysql 中,QUARTER(日期字段) 函数返回给定日期值(从1到4的数字)的一年的四分之一。

  • 1月至3月返回1

  • 4月至6月返回2

  • 7月至9月返回3

  • 10月至12月返回4

在oracle中,可使用 to_char(日期字段,'Q') 替换

 

21 字符集不匹配问题

原因可能是字段类型不一致的原因,比如,两个字段一个是VARCHAR2,一个是NVARCHAR2

或者

是在union时,所联接的两块数据,对应的字段类型不一致,一边是VARCHAR2,一边是NVARCHAR2。

需要先对应到具体哪个字段不一致,然后其中一个进行转换。

目前遇到的情况,一般是查询中,有字段是写死的值, 用来做union或者与其他字段比较,而对应的字段是另一个数据类型。比如:

   select nianyue,'全部' as VALUE_NAME_CN,count(1) shu
                    from (
                              SELECT distinct a.FUND_ID
                                            ,year(a.ESTABLISH_DATE)nianyue
                              from fund_class a
                                      INNER JOIN fund_issue b on a.SECURITY_ID = b.SECURITY_ID and b.RAISE_METHOD = '1'
                          )a group by nianyue
            select distinct a.FUND_ID
                                            ,year(b.ESTABLISH_DATE)nianyue
                                            ,d.VALUE_NAME_CN
                              from fund_class a
                                      INNER JOIN fund_issue b on a.SECURITY_ID = b.SECURITY_ID and b.RAISE_METHOD = '1' and b.ESTABLISH_DATE is not null
                                      join fund_type c on a.SECURITY_ID = c.SECURITY_ID and c.CODE_TYPE_ID = '40123'
                                      join sys_code d on d.CODE_TYPE_ID = c.CODE_TYPE_ID and left(c.VALUE_NUM_CD,8) = d.VALUE_NUM_CD

以上两段sql中,VALUE_NAME_CN字段,上面的对应写死的值,下面的对应的实际字段,而实际字段的类型是NVARCHAR2,这个时候就会有字符集不一致的问题。

修改方案就是,将写死的值的类型转换一下就好了,Translate('全部' USING NCHAR_CS) as VALUE_NAME_CN

 

22 ORA-01799: 列不能外部联接到子查询

原因:Oracle 不支持 在 join中存在子查询,效率太低。

解决方案:先查询出关联表的关联列,条件列,以及其它需要的列,查询结果集作为一个表,再让其它表来关联这个结果集

例子:

修改前

SELECT DISTINCT a.PERSON_ID personId, g.manager_type investmentType
      FROM (SELECT PERSON_ID, max(POSITION) POSITION
      FROM fund_manager_new
      WHERE POSITION = 'FM'
      and PERSON_ID in <foreach collection="personIds" item="personId" open="(" close=")" separator=",">#{personId}</foreach>
      GROUP BY PERSON_ID) a
      LEFT JOIN fund_manager_rating_dy g ON a.PERSON_ID = g.PERSON_ID
      AND g.END_DATE = (SELECT max(END_DATE) FROM fund_manager_rating_dy)
 

修改后

        SELECT DISTINCT a.PERSON_ID personId, g.manager_type investmentType
      FROM (SELECT PERSON_ID, max(POSITION) POSITION
      FROM fund_manager_new
      WHERE POSITION = 'FM'
      and PERSON_ID in <foreach collection="personIds" item="personId" open="(" close=")" separator=",">#{personId}</foreach>
      GROUP BY PERSON_ID) a
      LEFT JOIN ( select PERSON_ID,manager_type from fund_manager_rating_dy
      where END_DATE = (SELECT max(END_DATE) FROM fund_manager_rating_dy)) g
          on a.PERSON_ID = g.PERSON_ID order by a.PERSON_ID

 

23 date_sub 函数

对应替换方式如下:

  oracle oracle
增减一小时 date_sub(createDate, interval -1 hour) date_sub(createDate, interval 1 hour) createDate+1/24 createDate-1/24
增减一天 date_sub(createDate, interval -1 day) date_sub(createDate, interval 1 day) createDate+1 createDate-1
增减一月 date_sub(createDate, interval -1 month) date_sub(createDate, interval 1 month) add_months(createDate, 1) add_months(createDate, -1)
增减一季度 date_sub(createDate, interval -3 month) date_sub(createDate, interval 3 month) add_months(createDate, 3) add_months(createDate, -3)
增减一年 date_sub(createDate, interval -1 year) date_sub(createDate, interval 1 year) add_months(createDate, 12) add_months(createDate, -12)
  listagg(c.SEC_SHORT_NAME, ',') within
      GROUP (order by rownum) as SEC_SHORT_NAME,

24 field 函数 自定义排序

ORACLE可以借助DECODE函数,自定义顺序排序:

DECODE(value,if 条件1,then 值1,if 条件2,then 值2,...,else 其他值)

例子:

mysql中自定义排序如下

ORDER BY FIELD(b.TYPE_NAME, '普通股票型', '偏股混合型', '短期纯债型', '中长期纯债型', '可转债型', '偏债混合型', '混合债券型(一级)', '混合债券型(二级)',
                      '平衡混合型', '灵活配置混合型', '被动指数股票型', '增强指数股票型', '被动指数债券型', 'QDII股票型', 'QDII债券型', 'QDII混合型', 'QDII其他',
                      '传统货币型', '短期理财型', '浮动净值型', 'FOF', 'REITs', '保本型', '传统封闭式', '商品型', '其他型')

等价于在oracle中的

ORDER BY DECODE(b.TYPE_NAME, '普通股票型', 1, '偏股混合型', 2, '短期纯债型', 3, '中长期纯债型', 4, '可转债型', 5,
                      '偏债混合型', 6, '混合债券型(一级)', 7, '混合债券型(二级)', 8,
                      '平衡混合型', 9, '灵活配置混合型', 10, '被动指数股票型', 11, '增强指数股票型', 12,
                      '被动指数债券型', 13, 'QDII股票型', 14, 'QDII债券型', 15, 'QDII混合型', 16, 'QDII其他', 17,
                      '传统货币型', 18, '短期理财型', 19, '浮动净值型', 20, 'FOF', 21, 'REITs', 22, '保本型', 23, '传统封闭式', 24, '商品型',25,
                      '其他型', 99)

 

25 date函数,截取日期

想将1997/1/8 10:30:27变为1997/1/8,在mysql中使用 date(时间字段)

在oracle中,使用 trunc(时间字段)

 

26 ORA-00907: 缺失右括号,子查询中不能有order by

oracle子查询中使用order by 会报错:ORA-00907: 缺失右括号

from 子句后面的内联视图是可以使用order by子句进行排序的。

所以,可以将对应的oder by 子查询语句再嵌套一层。

改造前

        SELECT CLOSE_INDEX FROM
      (( SELECT CLOSE_INDEX,TRADE_DATE FROM mkt_idxd
      WHERE INDEX_ID = 1782 AND TRADE_DATE &lt; #{date} ORDER BY TRADE_DATE DESC LIMIT 1)
      UNION
      (SELECT CLOSE_INDEX,TRADE_DATE FROM mkt_idxd
      WHERE INDEX_ID = 1782 AND TRADE_DATE >= #{date} ORDER BY TRADE_DATE)) t
      ORDER BY TRADE_DATE

改造后:

        SELECT CLOSE_INDEX FROM
      (( SELECT * from ( SELECT CLOSE_INDEX,TRADE_DATE FROM mkt_idxd
      WHERE INDEX_ID = 1782 AND TRADE_DATE &lt; #{date} and rownum=1 ORDER BY TRADE_DATE DESC ) a1 )
      UNION
        ( SELECT * from (SELECT CLOSE_INDEX,TRADE_DATE FROM mkt_idxd
      WHERE INDEX_ID = 1782 AND TRADE_DATE >= #{date} ORDER BY TRADE_DATE) a2) ) t
      ORDER BY TRADE_DATE

改动点就是将原order by 子句,再嵌套一层,select * from table order by create_time 改为 select * from (原子句)

 

 

27 ORA-01791:不是SELECTed表达式

SQL 语句是先执行 distinct 去重后,再使用 order by 进行排序的。所以如果在 order by 需要排序的字段,没有在 distinct 后的字段中,就会抛错。

解决方案:

在 distinct 后加入需要排序的字段即可。

 

28 limit 问题

oracle 中没有limit,可以使用rownum替换

但是在语句中存在order by 排序时,单纯的将limit替换为rownum是不对的,因为rownum是在order by排序执行之前设置的值,针对带有order by的语句,需要使用 fetch first关键字进行替换

例如:

select SECURITY_ID from MD_SECURITY  order by SECURITY_ID limit 1

转换为oracle

select SECURITY_ID from MD_SECURITY  order by SECURITY_ID  fetch first 1 rows only

即: 将 limit 替换为 fetch first {需要数据行数} rows only

详细内容可参考:https://www.cnblogs.com/CandiceW/p/10030936.html

to_date(sysdate)

29 CURDATE()函数

CURDATE()函数值为不包括时分秒的值,所以替换的时候,要替换为to_date(sysdate)

 

30 @自定义变量问题

lag与lead函数是跟偏移量相关的两个分析函数,通过这两个函数可以在一次查询中取出同一字段的前N行的数据(lag)和后N行的数据(lead)作为独立的列,从而更方便地进行进行数据过滤。这种操作可以代替表的自联接,并且LAG和LEAD有更高的效率。

over()表示 lag()与lead()操作的数据都在over()的范围内,他里面可以使用partition by 语句(用于分组) order by 语句(用于排序)。partition by a order by b表示以a字段进行分组,再 以b字段进行排序,对数据进行查询。

  例如:lead(field, num, defaultvalue) field需要查找的字段,num往后查找的num行的数据,defaultvalue没有符合条件的默认值。

 

窗口分析函数:

sum() over ()

下面列一下开窗函数与分析函数搭配使用的情况:

1.有partition by有order by : 在partition by分组下,按照不同的order by 字段 实现递增汇总

2.有partition by无order by: 实现分组内所有数据的汇总

3.无partition by有order by : 直接按order by 字段实现递增汇总

4.无partition by无order by: 所有数据相加

 

当然,除了使用sum() over(),还有

count() over(partition by ... order by ...):求分组后的总数。 max() over(partition by ... order by ...):求分组后的最大值。 min() over(partition by ... order by ...):求分组后的最小值。 avg() over(partition by ... order by ...):求分组后的平均值。 lag() over(partition by ... order by ...):取出前n行数据。  

lead() over(partition by ... order by ...):取出后n行数据。

 

原sql:

(SELECT z1.*,IF(z1.SECURITY_ID=@SECURITY_ID,cast(@shu as DECIMAL(20,4)),null) AS HOLD_VOLUME_z1,
      @SECURITY_ID:=SECURITY_ID,@shu:= HOLD_VOLUME_z
      from
      (SELECT REPORT_DATE,SECURITY_ID,TICKER_SYMBOL,SEC_SHORT_NAME,TYPE_NAME,sum(HOLD_FUND) HOLD_FUND_z,sum(HOLD_INST) HOLD_INST_z,sum(MARKET_VALUE) MARKET_VALUE_z,sum(RATIO_IN_FLOAT_A) RATIO_IN_FLOAT_A_z,sum(HOLD_VOLUME) HOLD_VOLUME_z
      from fund_mt_holdkey_type
      where CATEGORY in <foreach collection="strategyCodes" item="code" open="(" close=")" separator=",">#{code}</foreach>
      group by REPORT_DATE,SECURITY_ID,TICKER_SYMBOL,SEC_SHORT_NAME,TYPE_NAME
      order by SECURITY_ID,REPORT_DATE) z1,(SELECT @SECURITY_ID:=NULL,@shu:= null)r)

改造后sql:

(SELECT
      case when z1_pre = SECURITY_ID then HOLD_VOLUME_z1_1 end as HOLD_VOLUME_z1,
      z1_1.*
      from (SELECT lag(z1.SECURITY_ID, 1, null) over (order by SECURITY_ID,REPORT_DATE) as z1_pre,
      lag(cast(z1.HOLD_VOLUME_z as DECIMAL(20,4)), 1, null) over (order by SECURITY_ID,REPORT_DATE) AS HOLD_VOLUME_z1_1,
      z1.*
      from
      (SELECT REPORT_DATE,SECURITY_ID,TICKER_SYMBOL,SEC_SHORT_NAME,TYPE_NAME,sum(HOLD_FUND) HOLD_FUND_z,sum(HOLD_INST) HOLD_INST_z,sum(MARKET_VALUE) MARKET_VALUE_z,sum(RATIO_IN_FLOAT_A) RATIO_IN_FLOAT_A_z,sum(HOLD_VOLUME) HOLD_VOLUME_z
      from fund_mt_holdkey_type
      where CATEGORY in <foreach collection="strategyCodes" item="code" open="(" close=")" separator=",">#{code}</foreach>
      group by REPORT_DATE,SECURITY_ID,TICKER_SYMBOL,SEC_SHORT_NAME,TYPE_NAME
      order by SECURITY_ID,REPORT_DATE) z1) z1_1)

 

31 substring 函数

直接替换为substr函数即可

 

32 year 函数获取日期的年份

year ( 日期字段 )

转换为oracle函数为:

extract(year from 日期字段)

 

33 force index 强制使用索引

SELECT /*+index(t pk_emp)*/* FROM EMP T   

--强制索引,/*.....*/第一个星星后不能有空格,里边内容结构为:加号index(表名 空格 索引名)。
--如果表用了别名,注释里的表也要使用别名。

 

 

34 join时没有on或者where条件

使用join或时inner joinon条件是可选的。这与ANSI标准不同,并且与几乎所有其他数据库不同。效果是cross join


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM