我正在使用PostgreSQL,我在Result
表中有一个名为Job
的列,
它包含2/3
,1/3
,2/3
等值。
例如:Job
表行是:
job_id result
------ ------
1 2/3
2 1/3
3 2/3
我希望以result
列的方式应用聚合函数
我可以得到如下结果:5/9
但Result
属于文字类型列,我们无法直接在该列上应用sum
/ avg
/ min
/ max
等功能。< / p>
任何人都可以使用查询本身建议任何其他方法来实现该结果吗?
所有建议都表示赞赏。
感谢。
答案 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
功能非常慢。