Как агрегировать без использования `GROUP BY`? - PullRequest
1 голос
/ 23 декабря 2011

У меня есть запрос, подобный следующему

SELECT a.*, b.*

(SELECT ATTR1, ATTR2, sum(QUANTITY) AS TOTAL_QTY,
ATTR3 FROM TABLE_A
WHERE ATTR4 > 0
GROUP BY ATTR1, ATTR2, ATTR3) a,

TABLE_B b

WHERE a.ATTR1 = b.ATTR1
AND a.ATTR2 = b.ATTR2

Мне нужно GROUP BY только ATTR1, чтобы вычислить правильное TOTAL_QTY, но единственная причина, по которой я группирую другие атрибуты, потому что Oracle требует, чтобы еслиПредложение GROUP BY присутствует, тогда все атрибуты SELECT должны быть также в предложении GROUP BY.

Это означает, что каждый раз, когда мне нужен атрибут в этом запросе из Table_A, мне нужно поместить его в GROUP BY тоже.Это не только выглядит некрасиво, но может оказать влияние на производительность и, возможно, непредвиденный побочный эффект.

Как переписать указанный выше запрос для вычисления TOTAL_QTY в каждой группе ATTR1 без выражения GROUP BY

Ответы [ 3 ]

8 голосов
/ 23 декабря 2011

Используйте аналитические функции Oracle. Измените встроенное представление для table_a на что-то вроде:

select attr1,
       attr2,
       sum(quantity) over (partition by attr1 order by attr1) as total_qty,
       attr3
from   table_a
where  attr4 > 0

Возможно, потребуется немного доработать, но это основная идея.

2 голосов
/ 23 декабря 2011

Попробуйте:

SELECT a.*, b.*
from (SELECT ATTR1, 
             max(ATTR2) ATTR2, 
             sum(QUANTITY) AS TOTAL_QTY,
             max(ATTR3) ATTR3 
      FROM TABLE_A
      WHERE ATTR4 > 0
      GROUP BY ATTR1) a,
      TABLE_B b
WHERE a.ATTR1 = b.ATTR1
AND a.ATTR2 = b.ATTR2

(Предполагается, что для каждого заданного значения ATTR1 значения ATTR2 и ATTR3 постоянны, т. Е. Они функционально зависят от него.)

1 голос
/ 23 декабря 2011

Из ваших ответов на мои комментарии выше, похоже, что вы хотите одну группу на значение ATTR1, и вы просто хотите любое значение ATTR2, принадлежащее этой группе.Вы можете сделать это просто, применив MAX или MIN к ATTR2 в групповом запросе:

SELECT a.*, b.*
FROM
(SELECT ATTR1, max(ATTR2) attr2, sum(QUANTITY) AS TOTAL_QTY,
ATTR3 FROM TABLE_A
WHERE ATTR4 > 0
GROUP BY ATTR1, ATTR2, ATTR3) a,
TABLE_B b
WHERE a.ATTR1 = b.ATTR1
AND a.ATTR2 = b.ATTR2

Таким образом, вы будете произвольно выбирать одно значение для ATTR2 из всехприсутствующие в группе.

...