如何在列cotainining字符串值上使用聚合函数?

时间:2011-07-07 07:29:09

标签: sql oracle postgresql aggregate-functions

我正在使用PostgreSQL,我在Result表中有一个名为Job的列, 它包含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等功能。< / p>

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

所有建议都表示赞赏。

感谢。

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

除了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功能非常慢。