与groupby聚合但在聚合列上具有不同的条件

时间:2014-07-26 11:18:15

标签: sql postgresql

我遇到过这样的问题。有一个表A,我想用一个`by by x order by diff(这是abs(x-y))递增聚合

x和y总是递增。当两个不同的x可以与相同的y

配对时,具有较小值的x将具有优先级
    x     y     diff
    1     2      1
    1     4      3
    1     6      5
    3     2      1
    3     4      1
    3     6      3
    4.5   2      3.5
    4.5   4      0.5
    4.5   6      1.5

我想要的聚合函数是:

取每组中与y具有最小差异的y(最小差值)。

但是拍摄的y不能重复使用。(例如,y = 2将被带入(x = 1)组,因此无法在(x = 3)组中重复使用)

预期结果:

    x     y     diff
    1     2     1
    3     4     1
    4.5   4     0.5
在纯SQL中,

似乎非常棘手。我正在使用PostgreSQL。真实的数据会很多 比这个想法拍摄的例子更复杂,更长久

3 个答案:

答案 0 :(得分:1)

如果正确理解了您的问题

test=# select * from A;
 x | y | diff 
---+---+------
 1 | 2 |    1
 1 | 4 |    3
 1 | 6 |    5
 3 | 2 |    1
 3 | 4 |    1
 3 | 6 |    3
 5 | 2 |    3
 5 | 4 |    1
 5 | 6 |    1
(9 rows)

test=# SELECT MIN(x) AS x, y FROM A WHERE diff = 1 GROUP BY y ORDER BY x;
 x | y 
---+---
 1 | 2
 3 | 4
 5 | 6
(3 rows)

SELECT MIN(x) AS x, y, MIN(diff) FROM A WHERE diff = 1 GROUP BY y ORDER BY x;
 x | y | min 
---+---+-----
 1 | 2 |   1
 3 | 4 |   1
 5 | 6 |   1
(3 rows)
如果不需要,可以删除

添加MIN(diff)

答案 1 :(得分:0)

试试这个

t1作为表名

d as diff

   with cte as (
   select x, y,d from t1 where d=(select min(d) from t1) order by x )
   select t1.x, min(t1.y), min(t1.d) from t1 inner join cte on 
   t1.x=cte.x and not t1.y   in (select y from cte where cte.x<t1.x)
   group by t1.x

答案 2 :(得分:0)

这更像是评论。

这个问题本质上是一个图形问题,即找到两个离散集(在这种情况下为x和y)之间的最短集合对。从技术上讲,这是加权二分图的最大匹配(见[here] [1])。我不认为这个问题是NP完全的。但这仍然会使得特别是在SQL中难以解决。

无论理论意义上是否很难(NP-complete被认为是#34;理论上很难&#34;),在SQL中很难做到。一个问题是贪婪的算法不起作用。同样的&#34; y&#34;值可能最接近 all X值。哪一个选择?那么,算法必须进一步研究。

我认为在SQL中做到这一点的唯一方法是详尽的方法。也就是说,生成所有可能的组合,然后检查符合您条件的组合。找到所有可能的组合需要生成X(或Y)的N因子组合。反过来,这需要大量的计算。我的第一个想法是使用递归CTE。但是,这只适用于小问题。