Sql 如何对包含字符串值的列使用聚合函数?
我正在使用PostgreSQL,在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
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来澄清他到底想要什么。