Получение самых низких значений в GROUP BY - PullRequest
1 голос
/ 20 декабря 2010
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 с.:

       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 ]

4 голосов
/ 20 декабря 2010

Вы ищете первые / последние агрегатные функции? Из-за функции MIN упорядочение по B в столбце first_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
0 голосов
/ 20 декабря 2010

Я думаю, что вы, вероятно, также назвали бы идею ниже под-выбора (или 2 под-выбора), но попробуйте в любом случае.
В противном случае вам не повезло, так как то, что вы хотите, требует выполнения двух разныхгруппировать по агрегатам, один по ключу, а другой по ключу и атрибуту a.И вы не можете сделать две разные группы агрегации в одном и том же операторе 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 
...