Sql 如何对包含字符串值的列使用聚合函数?

Sql 如何对包含字符串值的列使用聚合函数?,sql,oracle,postgresql,aggregate-functions,Sql,Oracle,Postgresql,Aggregate Functions,我正在使用PostgreSQL,在Job表中有一列名为Result, 它包含像2/3,1/3,2/3这样的值 例如:作业表行为: job_id result ------ ------ 1 2/3 2 1/3 3 2/3 我想在result列上应用聚合函数,以便 我可以得到如下结果:5/9 但是Result是文本类型列,我们不能直接在该列上应用sum/avg/min/max等函数 有人能建议使用查询本身实现该结果的其他方法吗 欢迎所有建议 谢谢。除了ypercub

我正在使用PostgreSQL,在
Job
表中有一列名为
Result
, 它包含像
2/3
1/3
2/3
这样的值

例如:
作业
表行为:

job_id result
------ ------
1      2/3
2      1/3
3      2/3
我想在
result
列上应用聚合函数,以便 我可以得到如下结果:
5/9

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

有人能建议使用查询本身实现该结果的其他方法吗

欢迎所有建议


谢谢。

除了ypercube的优秀答案之外,如果你想简化分数,你需要找到最大公约数

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
下面是一个存储函数的伪代码,它可以生成:

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
是一个非常慢的函数。

如果
result
列中的数字不是很小,而是说
32/6734513、467/12345679、1/98765432011
位置(“/”,result)
应该是
instr(result“/”)
对于已固定的
选择
。不过,不确定连接。连接应该是
|
否?@Aaron:
SUM(a)/SUM(b)
并不总是等于
AVG(a/b)
。事实上,几乎没有,只有在非常特殊的情况下。@Aaron:我想应该由OP来澄清他到底想要什么。