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