【问题标题】:Get the sum of particular values in a column via sql通过sql获取列中特定值的总和
【发布时间】:2022-01-22 15:05:05
【问题描述】:

我有一列包含不同的缺勤值 -

abs_table

absence_type value person_number regular_measure_hours
FLT 8 10 90
VAC 9 10
JUR 1 10
LOA 6.5 10
PAID 2 10
FLT 10 1 80
VAC 9 1
JUR 10 1

查询:

SELECT WHEN absence_type IN ('FLT', 'JUR', 'BRV', 'LOD', 'PAID') THEN 
            regular_measure_hours 
            - SUM(VALUE) OVER (PARTITION BY person_number value 
                               ORDER BY person_number) 
        ELSE regular_measure_hours,
       person_number
  FROM abs_table

如果缺席类型在其中任何一个中-('FLT','JUR','BRV','LOD','PAID'),那么我需要用regular_measure_hours减去那些“值”列的总和

在大多数情况下,上列中的总和并没有给我正确的结果。

期望的输出

person_number regular_measure_hours
10 79
1 60

如何调整分区的总和以获得正确的结果

【问题讨论】:

  • 您真的有一张与abs_table 完全相同的表,其中regular_measure_hours 对每个不同的人都有一个非空值吗?这看起来像是一个非常有缺陷的数据模型。或者您实际上是否有正确的模型(至少两个表;“常规测量时间”存储在与“缺勤”无关的单独的较小表中),并且您向我们展示的是您在尝试中计算的中间结果解决问题?

标签: sql oracle


【解决方案1】:

按 PERSON_NUMBER 分组,仅针对这 5 种类型。

SELECT
 PERSON_NUMBER, 
 SUM(regular_measure_hours)
 - SUM(CASE 
       WHEN Absence_type IN ('FLT','JUR','BRV','LOD','PAID')
       THEN VALUE
       ELSE 0
       END) as regular_measure_hours
FROM abs_table
WHERE (Absence_type IN ('FLT','JUR','BRV','LOD','PAID')
   OR regular_measure_hours IS NOT NULL) 
GROUP BY PERSON_NUMBER
ORDER BY PERSON_NUMBER

【讨论】:

    【解决方案2】:

    您不需要分析 SUM() 函数而是条件聚合,同时考虑 NVL() 以便用 替换 NULL 值,例如

    SELECT SUM(CASE
             WHEN absence_type IN ('FLT', 'JUR', 'BRV', 'LOD', 'PAID') THEN          
              NVL(regular_measure_hours,0) -NVL(value,0) 
           END) AS regular_measure_hours,
           person_number
      FROM abs_table
     GROUP BY person_number
    

    Demo

    【讨论】:

    • 数据模型看起来很奇怪;一方面,我不相信我们可以假设“常规测量时间”值(非空值)出现在缺勤类型为 FLT、JUR 等之一的行中。它可能出现在一行中缺勤类型 VAC,例如(对于只有 VACation、没有陪审员职责等的员工)
    • @mathguy 你说的很对。我们都依赖假设。
    【解决方案3】:

    对于您的单表数据模型(假设这是您的真实模型),这非常荒谬,您需要这样的聚合:

    select person_number,
           sum(regular_measure_hours) -
             nvl(sum(case when absence_type in ('FLT', 'JUR', 'BRV', 'LOD', 'PAID') 
                          then value end), 0) as adjusted_hours
    from   abs_table
    group  by person_number
    ;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-09
      • 1970-01-01
      • 2014-05-29
      • 1970-01-01
      • 2018-06-04
      相关资源
      最近更新 更多