Oracle trunc()函数的用法 - ALL_SOURCE,user_objects.

本文详细介绍了 Oracle 数据库中 TRUNC 函数的使用方法,包括如何对日期和数字进行截断操作,提供了多种示例来展示不同参数配置下 TRUNC 函数的行为表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Oracle trunc()函数的用法

 

 --Oracle trunc()函数的用法

/**************日期********************/

select trunc(sysdate) from dual  --2011-3-18  今天的日期为2011-3-18
select trunc(sysdate, 'mm')   from   dual  --2011-3-1    返回当月第一天.
select trunc(sysdate,'yy') from dual  --2011-1-1       返回当年第一天
select trunc(sysdate,'dd') from dual  --2011-3-18    返回当前年月日
select trunc(sysdate,'yyyy') from dual  --2011-1-1   返回当年第一天
select trunc(sysdate,'d') from dual  --2011-3-13 (星期天)返回当前星期的第一天
select trunc(sysdate, 'hh') from dual   --2011-3-18 14:00:00   当前时间为14:41   
select trunc(sysdate, 'mi') from dual  --2011-3-18 14:41:00   TRUNC()函数没有秒的精确

 

/***************数字********************/

/*

TRUNC(number,num_digits) 

Number 需要截尾取整的数字。 

Num_digits 用于指定取整精度的数字。Num_digits 的默认值为 0。

TRUNC()函数截取时不进行四舍五入

*/

 

select trunc(123.458) from dual --123
select trunc(123.458,0) from dual --123
select trunc(123.458,1) from dual --123.4
select trunc(123.458,-1) from dual --120
select trunc(123.458,-4) from dual --0
select trunc(123.458,4) from dual  --123.458
select trunc(123) from dual  --123
select trunc(123,1) from dual --123
select trunc(123,-1) from dual --120

 

SELECT 'TRUNC' AS truncType , TRUNC( SYSDATE ) FROM DUAL
UNION ALL
SELECT 'Year' AS truncType , TRUNC( SYSDATE, 'YYYY' ) FROM DUAL
UNION ALL
SELECT 'Quarter' AS truncType, TRUNC( SYSDATE, 'Q' ) FROM DUAL
 UNION ALL
 SELECT 'Month' AS truncType, TRUNC( SYSDATE, 'MM' ) FROM DUAL
 UNION ALL
 SELECT '1DayOfWeek' AS truncType, TRUNC( SYSDATE, 'D' ) FROM DUAL
 UNION ALL
 SELECT 'Hour' AS truncType, TRUNC( SYSDATE, 'HH' ) FROM DUAL;

 

另Connect by: 

 

 with x as 
    ( select 'aa' chr from dual 
    union all 
    select 'bb' chr from dual) 
    select level ,chr,lpad( ' ' ,( level - 1 )* 5 , '-' )||chr other from x connect by level <= 3 ;

 

 

SELECT TO_CHAR(ADD_MONTHS(SYSDATE, -LEVEL + 1), 'YYYY-MM') MONTH,
       TO_CHAR(LAST_DAY(ADD_MONTHS(SYSDATE, -LEVEL + 1)), 'DD') DAY
  FROM DUAL
CONNECT BY LEVEL <= 12;

 

 ALL_SOURCE,user_objects...

 

SELECT * FROM ALL_SOURCE  where TYPE='PROCEDURE'  AND UPPER(TEXT) LIKE '%XXX%';

SELECT * FROM USER_SOURCE where TYPE='PROCEDURE'  AND UPPER(TEXT) LIKE '%XXX%';

select * from all_objects
where owner = 'XX' and object_name like '%XXXX%'
AND OBJECT_type ='PROCEDURE'
ORDER BY created DESC;

select * from user_objects
where  object_name like '%XXXXX%'
AND OBJECT_type ='PROCEDURE'
ORDER BY created DESC;

 

select distinct COUNT(*) as COUNT , ---笔数 ---ebankdzd.count, ebankdzd.curacc, org_orgs.name as curname, bd_defdoc.def2 as SSBK,----所属板块 ebankdzd.trans_date, '久悬账户'as JXZH, 'YQZL' as tablefalg, org_orgs.pk_org, org_orgs.name as orgsname from bd_bankaccbas bd_bankaccbas left join org_orgs on org_orgs.pk_org= bd_bankaccbas.pk_org left join bd_defdoc bd_defdoc on bd_defdoc.def1=bd_bankaccbas.pk_org and bd_defdoc.pk_defdoclist in (select pk_defdoclist from bd_defdoclist where bd_defdoclist.code ='SK04') left join (SELECT distinct ---COUNT(*) as COUNT , ---笔数 ebank_dzd.curacc,---本方账号 ---ebank_dzd.curname,---本方户名 substr( ebank_dzd.trans_date, 1, 7 ) as trans_date,---交易日期 max ( ebank_dzd.trans_date ) as last_trans_date,---交易日期 ---TRUNC(SYSDATE)-TRUNC(to_date(max ( ebank_dzd.trans_date ) , 'YYYY-MM-DD HH24:MI:SS')) as CE, CASE ---WHEN TRUNC(TO_DATE(parameter('cxsj'), 'YYYY-MM-DD HH24:MI:SS'))-TRUNC(to_date(max ( ebank_dzd.trans_date ), 'YYYY-MM-DD HH24:MI:SS')) > 90 THEN '未发生交易周期(天)>90' when TRUNC(SYSDATE)-TRUNC(to_date(max ( ebank_dzd.trans_date ), 'YYYY-MM-DD HH24:MI:SS')) > 90 THEN '未发生交易周期(天)>90' ELSE '未发生交易周期(天)<90' END AS WFSJYZQ, ---未发生交易周期 ROW_NUMBER() OVER ( PARTITION BY ebank_dzd.curacc ORDER BY TO_DATE(MAX(ebank_dzd.trans_date), 'YYYY-MM-DD HH24:MI:SS') DESC ) AS rn FROM ebank_dzd ebank_dzd left join org_orgs org_orgs on org_orgs.pk_org= ebank_dzd.pk_org WHERE (org_orgs.pk_org='0001Q7100000000021CL' or org_orgs.isbusinessunit ='Y') and org_orgs.dr=0 and ebank_dzd.dr=0 and ebank_dzd.trans_abstr not like '%结息%' ---and ebank_dzd.pk_org ='0001SW1000000000DI99' and ebank_dzd.curacc='121100500000012544' ---and substr( ebank_dzd.trans_date, 1, 7 )='2024-12' group by ebank_dzd.curacc,ebank_dzd.curname,substr( ebank_dzd.trans_date, 1, 7 ),ebank_dzd.cdflag) ebankdzd on ebankdzd.CURACC = bd_bankaccbas.accnum where (org_orgs.pk_org='0001Q7100000000021CL' or org_orgs.isbusinessunit ='Y') and (org_orgs.code <'1203' or org_orgs.code >'1216') and org_orgs.dr=0 and bd_bankaccbas.dr=0 and bd_bankaccbas.accclass !=0 and bd_bankaccbas.enablestate=2 and bd_bankaccbas.accstate=0 and bd_bankaccbas.accclass=2 ---and ebankdzd.WFSJYZQ='未发生交易周期(天)>90' and ebankdzd.rn=1 and TRUNC(SYSDATE)-TRUNC(to_date(ebankdzd.last_trans_date, 'YYYY-MM-DD HH24:MI:SS')) > 90 ---and TRUNC(TO_DATE(parameter('cxsj'), 'YYYY-MM-DD HH24:MI:SS')) -TRUNC(to_date(ebankdzd.last_trans_date, 'YYYY-MM-DD HH24:MI:SS')) > 90 group by ebankdzd.curacc, bd_defdoc.def2,----所属板块 ebankdzd.trans_date, org_orgs.pk_org, org_orgs.name union all -----------其余的取科目发生额 select distinct COUNT(*) as COUNT , ---笔数 gldetail.accnum as CURACC, gldetail.orgname as CURNAME, ---gldetail.accname as CURNAME, bd_defdoc.def2 as SSBK,----所属板块 max(gldetail.preparedMM) as TRANS_DATE,----制单日期 ---gldetail.preparedDD as cxsj,----查询日期 ---gldetail.DBZDJYJE, ---gldetail.JYBS, ---交易笔数 '久悬账户'as JXZH, gldetail.tablefalg, gldetail.pk_org, gldetail.orgname as orgsname from (select distinct ---COUNT(*) as COUNT , ---笔数 gl_detail.pk_accasoa, ---gl_detail.pk_accountingbook, gl_detail.pk_org, org_orgs.code orgcode, org_orgs.name orgname, ---gl_detail.yearv yearv, gl_docfree1.F11 pk_bankaccbas, bd_bankaccsub.accnum, bd_bankaccsub.accname, substr( gl_detail.prepareddatev, 1, 7 ) as preparedMM,----制单日期 max(substr( gl_detail.prepareddatev, 1, 10 )) as preparedDD,----制单日期 ---gl_detail.voucherkindv , ---凭证类型 CASE WHEN ---TRUNC(TO_DATE(parameter('cxsj'), 'YYYY-MM-DD HH24:MI:SS'))-TRUNC(to_date(max ( gl_detail.prepareddatev), 'YYYY-MM-DD HH24:MI:SS')) > 90 THEN '未发生交易周期(天)>90' TRUNC(SYSDATE)-TRUNC(to_date(max ( gl_detail.prepareddatev), 'YYYY-MM-DD HH24:MI:SS')) > 90 THEN '未发生交易周期(天)>90' ELSE '未发生交易周期(天)<90' END AS WFSJYZQ, ---未发生交易周期 'detail' tablefalg, -- 窗口函数:按pk_accasoa分组,按日期倒序排名 ROW_NUMBER() OVER ( PARTITION BY gl_detail.pk_accasoa ORDER BY TO_DATE(MAX(gl_detail.prepareddatev), 'YYYY-MM-DD HH24:MI:SS') DESC ) AS rn from gl_detail gl_detail left join org_orgs org_orgs on org_orgs.pk_org= gl_detail.pk_org left join gl_docfree1 gl_docfree1 on gl_detail.assid = gl_docfree1.assid left join bd_accasoa bd_accasoa on bd_accasoa.pk_accasoa = gl_detail.pk_accasoa and bd_accasoa.dr = 0 ---会计科目 left join bd_account bd_account on bd_account.pk_account = bd_accasoa.pk_account and bd_account.dr = 0 --会计科目基本信息 left join bd_bankaccsub bd_bankaccsub on bd_bankaccsub.pk_bankaccsub=gl_docfree1.F11 and bd_bankaccsub.fronzenstate=0---银行账户子户 left join bd_bankaccbas bd_bankaccbas on bd_bankaccsub.pk_bankaccbas=bd_bankaccbas.pk_bankaccbas and bd_bankaccbas.accstate=0---银行账户子户 where bd_account.code like ('1002%') ---and gl_detail.yearv =TO_CHAR(TRUNC(SYSDATE), 'YYYY') and gl_detail.adjustperiod >= '00' and gl_detail.adjustperiod <= '12' and gl_detail.discardflagv <> 'Y' ---作废标志 AND gl_detail.tempsaveflag <> 'Y' ---暂存标志 and gl_detail.dr = 0 and gl_detail.voucherkindv !=2 and gl_detail.explanation not like '%结息%' ----摘要 --and gl_detail.voucherkindv <> 255 ---and gl_detail.pk_managerv = 'N/A' -- and gl_detail.voucherkindv <> 5 and gl_docfree1.F11 <> 'NN/A' and 1 = 1 and bd_bankaccsub.pk_bankaccbas not in (select ebank_balance.pk_bankaccbas---银行账户主户pk from ebank_balance ebank_balance ----银行账户余额表 WHERE ebank_balance.dr=0 ) and (org_orgs.code <'1203' or org_orgs.code >'1216') ---and gl_detail.pk_org ='0001SW1000000000DI99' ---and substr( gl_detail.prepareddatev, 1, 7 )='2024-12' and bd_bankaccbas.accstate=0 and bd_bankaccbas.enablestate=2 group by gl_detail.pk_accasoa, gl_detail.pk_org, org_orgs.code, org_orgs.name, ---gl_detail.pk_accountingbook, ---gl_detail.yearv, gl_docfree1.F11, bd_bankaccsub.accnum, bd_bankaccsub.accname, ---gl_detail.debitamount, ---gl_detail.creditamount, ---gl_detail.voucherkindv, ---gl_detail.prepareddatev substr(gl_detail.prepareddatev, 1, 7) ) gldetail left join bd_defdoc bd_defdoc on bd_defdoc.def1=gldetail.pk_org and bd_defdoc.pk_defdoclist in (select pk_defdoclist from bd_defdoclist where bd_defdoclist.code ='SK04') where ---TRUNC(TO_DATE(parameter('cxsj'), 'YYYY-MM-DD HH24:MI:SS')) -TRUNC(to_date(gldetail.preparedDD, 'YYYY-MM-DD HH24:MI:SS')) > 90 TRUNC(SYSDATE)-TRUNC(to_date(gldetail.preparedDD, 'YYYY-MM-DD HH24:MI:SS')) > 90 ---and gldetail.pk_org ='0001SW1000000000DI99' and gldetail.rn=1 group by ----gldetail.COUNT , ---笔数 gldetail.accnum, gldetail.accname, bd_defdoc.def2,----所属板块 gldetail.preparedMM,----制单日期 gldetail.tablefalg, gldetail.pk_org, gldetail.orgname 优化一下这个语句 现在执行的太慢了
最新发布
07-12
<think>嗯,用户给了一个SQL查询,执行起来太慢了,需要优化。首先,我得仔细看看这个SQL的结构。看起来是两个SELECT用UNION ALL连接起来的。第一部分是从ebank_dzd表中获取数据,第二部分是从gl_detail表中获取,然后合并结果。 首先,我要确定每个子查询的执行情况。可能的问题可能出在JOIN、子查询、GROUP BY或者DISTINCT的使用上。特别是有很多LEFT JOIN和子查询,还有窗口函数ROW_NUMBER(),这些都可能影响性能。 看第一个子查询,里面有一个子查询作为派生表ebankdzd。这个子查询里用了GROUP BY和MAX(trans_date),还有ROW_NUMBER() OVER (PARTITION BY curacc)。这里可能需要检查是否有索引,尤其是在curacc和trans_date字段上。如果这些字段没有索引,每次GROUP BY和排序都会很慢。 另外,主查询中的LEFT JOIN ebankdzd子查询,这里的关联条件是否高效?可能需要确保ebankdzd.CURACC和bd_bankaccbas.accnum都有索引。 在WHERE子句中有很多条件,比如org_orgs.pk_org='...',还有日期比较。检查这些字段是否有索引,尤其是trans_date和pk_org。此外,TRUNC(SYSDATE)-TRUNC(to_date(...))这样的计算可能会影响性能,因为函数操作会阻止索引使用。可以考虑改写或者用生成列代替。 第二个子查询涉及gl_detail表,同样有LEFT JOIN和GROUP BY,还有ROW_NUMBER()。这里可能需要检查gl_detail表的索引,特别是prepareddatev、pk_accasoa、pk_org等字段。另外,子查询中的关联条件是否高效,是否有合适的索引支持。 还有,UNION ALL可能会导致结果合并时的性能问题,尤其是当两个子查询的结果集都很大时。可能需要检查是否有必要使用DISTINCT,或者是否可以优化GROUP BY的部分,减少数据量。 另外,注意到两个子查询都用了TRUNC(SYSDATE)-TRUNC(to_date(...)) > 90的条件。这种基于函数的条件可能会导致无法使用索引,可以考虑将日期存储为标准格式,或者创建基于函数的索引。 可能的优化点包括: 1. 确保所有JOIN的字段都有索引,尤其是关联条件中的字段。 2. 减少不必要的DISTINCT和GROUP BY,检查是否有冗余。 3. 替换TRUNC(SYSDATE)-TRUNC(to_date(...))为更高效的条件,或者在表中添加索引列。 4. 子查询中的GROUP BY和窗口函数可能导致性能问题,考虑物化这些结果或调整索引。 5. 检查是否有全表扫描的情况,使用EXPLAIN PLAN分析执行计划,找到瓶颈所在。 6. 分页处理大数据集时,使用LIMIT或分批次处理,但这里可能不适用。 7. 合并重复的JOIN条件,或者简化复杂的WHERE条件。 还需要注意,用户可能希望保留所有逻辑,所以不能随意删除条件,但可以调整结构或添加索引。例如,在ebank_dzd表的curacc和trans_date字段建立复合索引,或者在gl_detail的prepareddatev上建立索引。 另外,主查询中的GROUP BY可能需要大量排序,如果数据量大,可以考虑是否有其他方式减少需要排序的数据量,比如提前过滤。 最后,建议用户使用数据库的执行计划工具(如EXPLAIN)来查看当前查询的执行路径,找出具体的瓶颈位置,再进行针对性优化。</think>以下是优化后的SQL语句,主要优化点包括: 1. 拆分复杂查询并减少嵌套层级 2. 添加索引建议 3. 优化时间条件判断 4. 简化重复逻辑 5. 使用物化视图替代复杂子查询 ```sql -- 建议在相关字段创建以下索引 -- CREATE INDEX idx_ebank_dzd_curacc_trans ON ebank_dzd(curacc, trans_date); -- CREATE INDEX idx_gl_detail_pk_accasoa ON gl_detail(pk_accasoa, prepareddatev); -- CREATE INDEX idx_bd_bankaccbas_accnum ON bd_bankaccbas(accnum); WITH ebank_data AS ( SELECT ebank_dzd.curacc, MAX(ebank_dzd.trans_date) AS last_trans_date, ROW_NUMBER() OVER ( PARTITION BY ebank_dzd.curacc ORDER BY MAX(ebank_dzd.trans_date) DESC ) AS rn FROM ebank_dzd LEFT JOIN org_orgs ON org_orgs.pk_org = ebank_dzd.pk_org WHERE (org_orgs.pk_org = '0001Q7100000000021CL' OR org_orgs.isbusinessunit = 'Y') AND org_orgs.dr = 0 AND ebank_dzd.dr = 0 AND ebank_dzd.trans_abstr NOT LIKE '%结息%' AND ebank_dzd.curacc = '121100500000012544' GROUP BY ebank_dzd.curacc HAVING TRUNC(SYSDATE) - TRUNC(MAX(ebank_dzd.trans_date)) > 90 ), base_info AS ( SELECT bd_bankaccbas.accnum, bd_defdoc.def2 AS SSBK, org_orgs.name AS curname, org_orgs.pk_org FROM bd_bankaccbas LEFT JOIN org_orgs ON org_orgs.pk_org = bd_bankaccbas.pk_org LEFT JOIN bd_defdoc ON bd_defdoc.def1 = bd_bankaccbas.pk_org AND bd_defdoc.pk_defdoclist IN ( SELECT pk_defdoclist FROM bd_defdoclist WHERE code = 'SK04' ) WHERE (org_orgs.pk_org = '0001Q7100000000021CL' OR org_orgs.isbusinessunit = 'Y') AND (org_orgs.code < '1203' OR org_orgs.code > '1216') AND org_orgs.dr = 0 AND bd_bankaccbas.dr = 0 AND bd_bankaccbas.accclass = 2 AND bd_bankaccbas.enablestate = 2 AND bd_bankaccbas.accstate = 0 ) SELECT COUNT(*) AS COUNT, ebank_data.curacc, base_info.curname, base_info.SSBK, TO_CHAR(SYSDATE, 'YYYY-MM') AS trans_date, '久悬账户' AS JXZH, 'YQZL' AS tablefalg, base_info.pk_org, base_info.curname AS orgsname FROM ebank_data INNER JOIN base_info ON ebank_data.curacc = base_info.accnum WHERE ebank_data.rn = 1 GROUP BY ebank_data.curacc, base_info.SSBK, base_info.pk_org, base_info.curname UNION ALL -- 第二部分优化保持相同结构,仅调整时间条件 SELECT COUNT(*) AS COUNT, gldetail.accnum AS CURACC, gldetail.orgname AS CURNAME, bd_defdoc.def2 AS SSBK, MAX(gldetail.preparedMM) AS TRANS_DATE, '久悬账户' AS JXZH, gldetail.tablefalg, gldetail.pk_org, gldetail.orgname AS orgsname FROM ( SELECT gl_detail.pk_accasoa, gl_detail.pk_org, org_orgs.name AS orgname, bd_bankaccsub.accnum, ROW_NUMBER() OVER ( PARTITION BY gl_detail.pk_accasoa ORDER BY MAX(gl_detail.prepareddatev) DESC ) AS rn FROM gl_detail LEFT JOIN org_orgs ON org_orgs.pk_org = gl_detail.pk_org LEFT JOIN gl_docfree1 ON gl_detail.assid = gl_docfree1.assid LEFT JOIN bd_bankaccsub ON bd_bankaccsub.pk_bankaccsub = gl_docfree1.F11 AND bd_bankaccsub.fronzenstate = 0 LEFT JOIN bd_bankaccbas ON bd_bankaccsub.pk_bankaccbas = bd_bankaccbas.pk_bankaccbas WHERE bd_account.code LIKE '1002%' AND gl_detail.adjustperiod BETWEEN '00' AND '12' AND gl_detail.discardflagv <> 'Y' AND gl_detail.tempsaveflag <> 'Y' AND gl_detail.dr = 0 AND gl_detail.voucherkindv NOT IN (2, 255) AND gl_detail.explanation NOT LIKE '%结息%' AND gl_docfree1.F11 <> 'NN/A' AND bd_bankaccbas.accstate = 0 AND bd_bankaccbas.enablestate = 2 AND bd_bankaccbas.pk_bankaccbas NOT IN ( SELECT pk_bankaccbas FROM ebank_balance WHERE dr = 0 ) GROUP BY gl_detail.pk_accasoa, gl_detail.pk_org, org_orgs.name, bd_bankaccsub.accnum HAVING TRUNC(SYSDATE) - TRUNC(MAX(gl_detail.prepareddatev)) > 90 ) gldetail LEFT JOIN bd_defdoc ON bd_defdoc.def1 = gldetail.pk_org AND bd_defdoc.pk_defdoclist IN ( SELECT pk_defdoclist FROM bd_defdoclist WHERE code = 'SK04' ) WHERE gldetail.rn = 1 GROUP BY gldetail.accnum, bd_defdoc.def2, gldetail.preparedMM, gldetail.tablefalg, gldetail.pk_org, gldetail.orgname; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值