如何在单个 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_dateDATE 列,则表达式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】:

如果durationend_datestart_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

要在一个查询中获取部分总和和总计,请使用 cuberollupgrouping 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 和更多列获取总金额的主要内容,如果未能解决你的问题,请参考以下文章

访问 Vb6 查询

按 4 个不同级别和总数字字段分组

Oracle SQL 查询部分包含所需结果

pl sql developer应用问题

oracle sql (toad) - 执行多个查询,保存到单个 excel 文件

mysql 实现同一个sql查询 分页数据 和总记录数