【问题标题】:SQL: multiply rows values per group [duplicate]SQL:每组乘以行值[重复]
【发布时间】:2021-09-08 16:48:06
【问题描述】:

我有一个像这样的表“MYTABLE”:

Id    name           gr      possibility
1     artv432        1           10
2     brtu52         1           5
3     gep2           1           2
4     cert9          2           12

我需要在每个组中将 possibility 列中的值相乘。 这是所需的输出:

gr            possibility     
1                100             -> 10*5*2
2                 12             ->   12

更新 1:

此代码不起作用。

select exp(sum(ln(Possibility)))

因为Possibility 是一个十进制值,例如可以是0.56。为了便于理解,我在这里使用了整数值。

【问题讨论】:

  • 没有。它仅在可能性是没有小数的数字时才有效。 (整数)
  • 你知道你有多少个小数吗?假设你有 3 位小数。您可以将所有值乘以 1000 以将其转换为整数吗?然后进行乘法运算,然后将结果除以 1000。
  • 其实有 0.012 , 0.105, 1,006 。
  • cast(exp(sum(ln(Possibility))) as decimal(20,5)) db<>fiddle

标签: sql oracle


【解决方案1】:

您可以创建用户定义的聚合函数:

CREATE OR REPLACE TYPE ProductAggregation AS OBJECT(
  value    NUMBER,

  STATIC FUNCTION ODCIAggregateInitialize(
    ctx         IN OUT ProductAggregation
  ) RETURN NUMBER,

  MEMBER FUNCTION ODCIAggregateIterate(
    self        IN OUT ProductAggregation,
    value       IN     NUMBER
  ) RETURN NUMBER,

  MEMBER FUNCTION ODCIAggregateTerminate(
    self        IN OUT ProductAggregation,
    returnValue    OUT NUMBER,
    flags       IN     NUMBER
  ) RETURN NUMBER,

  MEMBER FUNCTION ODCIAggregateMerge(
    self        IN OUT ProductAggregation,
    ctx         IN OUT ProductAggregation
  ) RETURN NUMBER
);
/

CREATE OR REPLACE TYPE BODY ProductAggregation
IS
  STATIC FUNCTION ODCIAggregateInitialize(
    ctx         IN OUT ProductAggregation
  ) RETURN NUMBER
  IS
  BEGIN
    ctx := ProductAggregation(1);
    RETURN ODCIConst.SUCCESS;
  END;

  MEMBER FUNCTION ODCIAggregateIterate(
    self        IN OUT ProductAggregation,
    value       IN     NUMBER
  ) RETURN NUMBER
  IS
  BEGIN
    self.value := self.value * value;
    RETURN ODCIConst.SUCCESS;
  END;

  MEMBER FUNCTION ODCIAggregateTerminate(
    self        IN OUT ProductAggregation,
    returnValue    OUT NUMBER,
    flags       IN     NUMBER
  ) RETURN NUMBER
  IS
  BEGIN
    returnValue := self.value;
    RETURN ODCIConst.SUCCESS;
  END;

  MEMBER FUNCTION ODCIAggregateMerge(
    self        IN OUT ProductAggregation,
    ctx         IN OUT ProductAggregation
  ) RETURN NUMBER
  IS
  BEGIN
    self.value := self.value * ctx.value;
    RETURN ODCIConst.SUCCESS;
  END;
END;
/

CREATE FUNCTION product( value NUMBER )
RETURN NUMBER
PARALLEL_ENABLE AGGREGATE USING ProductAggregation;
/

那么,对于样本数据:

CREATE TABLE table_name (Id, name, gr, possibility) AS
SELECT 1, 'artv432', 1, 10.0 FROM DUAL UNION ALL
SELECT 2, 'brtu52',  1,  5.0 FROM DUAL UNION ALL
SELECT 3, 'gep2',    1,  2.0 FROM DUAL UNION ALL
SELECT 4, 'cert9',   2, 12.0 FROM DUAL UNION ALL
SELECT 5, 'abc',     3,  0.1 FROM DUAL UNION ALL
SELECT 6, 'def',     3,  0.2 FROM DUAL UNION ALL
SELECT 7, 'ghi',     4, NULL FROM DUAL UNION ALL
SELECT 8, 'jki',     4,  5.0 FROM DUAL;

查询:

SELECT gr,
       product(possibility)
FROM   table_name
GROUP BY gr;

输出:

GR PRODUCT(POSSIBILITY)
1 100
2 12
3 .02
4 5

db小提琴here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多