获得GROUP BY中的最低值

时间:2010-12-20 15:51:49

标签: sql oracle greatest-n-per-group

WITH test_data AS (
  SELECT 1 key, 1 a, 2 b FROM dual UNION ALL  --# Lowest a for key=1
  SELECT 1 key, 2 a, 1 b FROM dual UNION ALL
  SELECT 2 key, 3 a, 3 b FROM dual UNION ALL  --# Lowest a for key=2, lowest b
  SELECT 2 key, 3 a, 4 b FROM dual UNION ALL
  SELECT 2 key, 4 a, 5 b FROM dual
)

我正在尝试按key进行分组,并检索最低a和相应的b(如果是关系,则为最低b),加上它的b s:

       KEY          A    FIRST_B      SUM_B
---------- ---------- ---------- ----------
         1          1          2          3
         2          3          3         12

我可以通过子选择

来实现这一点
SELECT key, MIN(a) AS a, first_b, SUM(b) AS sum_b
FROM (
  SELECT key, a, b,
         FIRST_VALUE(b) OVER (PARTITION BY key ORDER BY a, b) AS first_b
  FROM test_data
)
GROUP BY key, first_b

但我想知道是否有办法避免子选择,比如

SELECT key, a, SUM(b) AS sum_b,
       MIN( FIRST_VALUE(b) OVER (PARTITION BY key ORDER BY a, b) ) AS first_b
FROM test_data
GROUP BY key, a

引发 ORA-30483:此处不允许使用窗口函数


先谢谢,彼得

2 个答案:

答案 0 :(得分:4)

您在寻找first /最后的聚合函数吗?由于MIN函数,在first_b列上按B排序应该是多余的,但这可能取决于您打算如何使用它。

WITH test_data AS (
  SELECT 1 key, 1 a, 2 b FROM dual UNION ALL  --# Lowest a for key=1
  SELECT 1 key, 2 a, 1 b FROM dual UNION ALL
  SELECT 2 key, 3 a, 3 b FROM dual UNION ALL  --# Lowest a for key=2, lowest b
  SELECT 2 key, 3 a, 4 b FROM dual UNION ALL
  SELECT 2 key, 4 a, 5 b FROM dual
)
select 
  key, 
  min(a) as a,
  min(b) keep (dense_rank first ORDER BY a, b) as first_b,
  SUM(b) AS sum_b
FROM test_data
GROUP BY key

答案 1 :(得分:0)

我认为您可能也会将这个想法称为子选择(或2个子选择),但无论如何都要尝试。
否则你运气不好,因为你想要的是你需要通过聚合执行两个不同的组,一个只在密钥上,一个在密钥上和一个属性上。并且您不能在同一SQL语句中通过聚合执行两个不同的组。因此,您至少需要两个不同的SQL语句,这些语句显然必须以某种方式组合。并且没有办法将两个不同SQL语句中的两个结果集合并为一个,而不将一个或另一个(或两者)视为一种或另一种的子选择。

   Select X.key, X.a, y.firstBm X.sum_b  
   From
    (SELECT tda.key, MIN(tda.a) a, 
        Min(case tdb.b) firstB, 
        SUM(tda.b) sum_b 
       FROM test_data tda
       Group By key) X
    Left Join
      (Select tda.key, a, 
        Min(b) firstB
       FROM test_data     
       Group By key, a) Y
    On Y.key = X.key  
       And Y.a = X.a