【问题标题】:How to use aggregate function on column cotainining string values?如何在包含字符串值的列上使用聚合函数?
【发布时间】:2011-07-07 07:29:09
【问题描述】:

我正在使用 PostgreSQL,我在 Job 表中有一个名为 Result 的列, 它包含2/31/32/3 等值。

例如:Job 表行是:

job_id result
------ ------
1      2/3
2      1/3
3      2/3

我想以这样的方式在result 列上应用聚合函数 我可以得到如下结果:5/9

但是Result是文本类型列,我们不能直接在该列上应用sum/avg/min/max等函数。

任何人都可以建议任何其他方法来使用查询本身来实现该结果吗?

感谢所有建议。

谢谢。

【问题讨论】:

  • 如果result 列的数字不是小数字而是说32/6734513, 467/12345679, 1/98765432011 会发生什么??

标签: sql oracle postgresql aggregate-functions


【解决方案1】:
SELECT SUM( dividend ) || '/' || SUM( divisor )
       AS FractionOfSums
     , AVG( dividend / divisor )        
       AS AverageOfFractions
FROM
  ( SELECT CAST(substr(result, 1, position('/' in result)-1 ) AS int)
           AS dividend
         , CAST(substr(result, position('/' in result)+1 ) AS int)
           AS divisor
    FROM rows
  ) AS division

【讨论】:

  • position('/', result) 对于 Oracle 应该是 instr(result, '/')
  • 修复了select。不过,不确定串联。
  • 连接应该是|| 否?
  • @Aaron: SUM(a) / SUM(b) 并不总是等于 AVG(a/b)。事实上,几乎从来没有,只有在非常特殊的情况下。
  • @Aaron:我想应该由 OP 来澄清他到底想要什么聚合。
【解决方案2】:

除了 ypercube 的出色答案之外,如果您想简化分数,您需要找到最大公约数。

这是一个可以生成这个的存储函数的伪代码:

CREATE FUNCTION gcd(x int, y int) RETURNS int DETERMINISTIC
BEGIN
  DECLARE dividend int;
  DECLARE divisor int;
  DECLARE remainder int;

  SET dividend := GREATEST(x, y);
  SET remainder := LEAST(x, y);

  WHILE remainder != 0 DO
    SET divisor = remainder;
    SET remainder = MOD(dividend, divisor);
    SET dividend = divisor;
  END WHILE;

  RETURN divisor;
END

现在您可以将查询重写为:

SELECT (dividend/MyGCD) || '/' || (divisor/MyGCD) as FractionOfSums
  , AverageOfFractions 
FROM ( 
  SELECT 
    SUM( dividend ) as dividend
    , SUM( divisor ) AS divisor      
    , gcd(SUM( dividend ),SUM( divisor )) as MyGCD 
    , AVG( dividend / divisor ) AS AverageOfFractions 
  FROM ( 
    SELECT CAST(substr(result, 1, position('/', result)-1 ) AS int) AS dividend
        , CAST(substr(result, position('/', result)+1 ) AS int) AS divisor    
    FROM rows ) AS division 
) as Elements 

请注意,GCD 是一个非常慢的函数。

【讨论】:

    猜你喜欢
    • 2016-08-02
    • 1970-01-01
    • 1970-01-01
    • 2015-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 1970-01-01
    相关资源
    最近更新 更多