【问题标题】:GROUP BY custom aggregateGROUP BY 自定义聚合
【发布时间】:2016-09-27 03:34:07
【问题描述】:

我正在尝试通过下面的聚合按子查询进行分组(我将查询简化为最基本的形式,group by n 查询)。

但我现在不需要使用最大值,而是需要以下启发式:

bar 范围为 0-2。我想按顺序从 2,0,1 中选择。但是我想在baroriginal值上原始加入。

我可以编写自定义聚合函数来返回正确的属性吗?我对如何将两者结合起来有点迷茫。

SELECT 
    FOO.bar2
FROM
   FOO
INNER JOIN(
    SELECT
        FOO.id,
        custom_aggrgate(bar)
    FROM
        FOO                    
    GROUP BY
        FOO.id            
    ) b ON FOO.bar = inverse_of_custom_aggrgate(bar) -- get org. value of bar to join by

【问题讨论】:

  • 你能提供一个输入值和你正在寻找的输出的例子吗?

标签: sql postgresql group-by aggregate-functions greatest-n-per-group


【解决方案1】:

最简单的解决方案是使用DISTINCT ONORDER BY 中的CASE 表达式:

我认为这是您真正想要的

SELECT DISTINCT ON (id) bar2
FROM   foo
ORDER  BY id, CASE bar WHEN 2 THEN -1 ELSE bar END;

无需自定义聚合函数。
无需再次加入。
不需要函数来反转所述自定义聚合函数的结果。

关于DISTINCT ON


问题中的查询在语法上无效,可能不是您想要的。固定语法后,它可能如下所示:

SELECT FOO.bar2
FROM   FOO
INNER  JOIN (
    SELECT FOO.id, custom_aggrgate(bar) AS bar
    FROM   FOO                    
    GROUP  BY FOO.id            
    ) b ON FOO.bar = inverse_of_custom_aggrgate(b.bar);

但这可能仍然是无稽之谈。如果bar 未定义为唯一的(在您的场景中这似乎不太可能),您会得到许多重复的行。这个可疑查询的等价物是:

SELECT f.bar2
FROM   foo f
JOIN  (
   SELECT DISTINCT ON (id) bar
   FROM   foo
   ORDER  BY id, CASE bar WHEN 2 THEN -1 ELSE bar END
   ) b USING (bar);

我不认为这是你需要的。

【讨论】:

    猜你喜欢
    • 2014-11-22
    • 2014-12-27
    • 1970-01-01
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    • 2014-12-08
    • 2016-04-29
    • 1970-01-01
    相关资源
    最近更新 更多