如何在单个 oracle SQL 查询和总金额中针对 person_number 和更多列获取总金额
Posted
技术标签:
【中文标题】如何在单个 oracle SQL 查询和总金额中针对 person_number 和更多列获取总金额【英文标题】:how to get total of amount against person_number and some more columns in a single oracle SQL query and grand amount 【发布时间】:2019-08-02 00:54:53 【问题描述】:我有一张表查询是这样的
SELECT
cost_center_name,
person_number,
person_full_name,
TO_DATE(TO_CHAR(wfc_start_date,'DD-MON-YYYY HH:MI:SS AM'),'DD-MON-YYYY HH:MI:SS AM') start_date,
TO_DATE(TO_CHAR(wfc_end_date,'DD-MON-YYYY HH:MI:SS AM'),'DD-MON-YYYY HH:MI:SS AM') end_date,
TO_CHAR(wfc_start_date,'DD-MON-YYYY HH:MI:SS AM') start_date_hours,
TO_CHAR(wfc_end_date,'DD-MON-YYYY HH:MI:SS AM') end_date_hours,
pay_code_name,
duration_dd_hh_mi_ss,
wage_amount,
FROM
XX_pay_type a
WHERE
person_number IN (
'102',
'103'
)
AND pay_period_ending_date = '20-APR-2019'
duration_dd_hh_mi_ss, 具有像 00:4:32:00 这样的值 00:3:20:00
我想要来自 sql 查询的 sum(wage_amount) 和 sum(duration_dd_hh_mi_ss) 针对 person_number 我也想要grand_total (wage_amount)
sum(duration_dd_hh_mi_ss) 在这种情况下将是 00:7:52:00
我试过 sum(wage_amount) over(partition by person_number) 但我不能得到总和(duration_dd_hh_mi_ss)对person_number和grand(wage_total)
【问题讨论】:
如果wfc_start_date
是DATE
列,则表达式TO_DATE(TO_CHAR(wfc_start_date,'DD-MON-YYYY HH:MI:SS AM'),'DD-MON-YYYY HH:MI:SS AM')
可以简化为wfc_start_date
。 从不,永远不要对已经是日期的值调用to_date()
。这将首先将date
值转换为varchar
,然后将varchar
转换回最初的date
。
【参考方案1】:
如果duration
是end_date
和start_date
的减法,则使用减法。不要跟随第一步。
1
否则使用to_dsinterval()。但是为了能够使用它我们需要将duration
中的第一个:
替换为空格,因为to_dsinterval
不接受这个参数。
select regexp_replace('00:2:32:00', ':', ' ', 1, 1) from dual; --> 00 2:32:00
select to_dsinterval(regexp_replace('00:2:32:00', ':', ' ', 1, 1)) from dual;
现在我们有了一些可以求和的区间。它是not trivial, but possible。字符串不能。
2
要在一个查询中获取部分总和和总计,请使用 cube
、rollup
或 grouping sets
的聚合。这是rollup
的示例:
-- sample data
with t(center, id, name, duration, wage_amount) as (
select 'C1', '102', 'Tim', '01:2:00:00', 80 from dual union all
select 'C1', '102', 'Tim', '00:0:32:00', 70 from dual union all
select 'C2', '102', 'Tim', '00:2:00:00', 100 from dual union all
select 'C2', '103', 'Bob', '00:2:00:00', 120 from dual )
-- end of sample data
查询:
select center, id, name, sum(wage_amount) amt,
numtodsinterval(sum(sysdate + to_dsinterval(regexp_replace(duration, ':', ' ', 1, 1))
- sysdate ), 'day') duration
from t
group by rollup((id, name), center)
结果:
CENTER ID NAME AMT DURATION
------ --- ---- ---------- -------------------
C1 102 Tim 150 +000000001 02:32:00
C2 102 Tim 100 +000000000 02:00:00
102 Tim 250 +000000001 04:32:00
C2 103 Bob 120 +000000000 02:00:00
103 Bob 120 +000000000 02:00:00
370 +000000001 06:32:00
您也可以从一开始就这样做,使用分析总和,这将为您提供附加列中的值。或者对您的数据和分组查询进行联合 (union all
)。
【讨论】:
在上述查询中 numtodsinterval(sum(sysdate + to_dsinterval(regexp_replace(duration, ':', ' ', 1, 1)) - sysdate ), 'day') 持续时间 它给出的持续时间为 +03 08:00:00.000000 我希望它只是小时和分钟【参考方案2】:'duration_dd_hh_mi_ss
' 列的数据类型是什么?
【讨论】:
DURATION_DD_HH_MI_SS VARCHAR2(50) 我希望 person_number 持续时间的总和(DURATION_DD_HH_MI_SS)的值为 00:00:40:00, 00:03:00:00, 00:05:10:00 天:hours:minutes:seconds 这里是 00:8:50:00以上是关于如何在单个 oracle SQL 查询和总金额中针对 person_number 和更多列获取总金额的主要内容,如果未能解决你的问题,请参考以下文章