2011-12-23 2 views
1

У меня есть запрос, как следующийКак объединить без использования `GROUP BY`?

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.

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

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

+2

Это характер агрегатов, которые вы должны группировать, иначе система не знает, что вы хотите суммировать или как сформировать строки. Единственный способ устранить этот эффект - использовать агрегат в других столбцах max (attr1), max (attr2), однако вы быстро увидите, почему group by является лучшим вариантом, если attr1 и attr2 имеют разные значения в разных строках для тот же столбец – xQbert

+0

«Oracle требует, чтобы, если предложение GROUP BY присутствует, все атрибуты SELECT также должны быть в предложении GROUP BY». Неправда - они также могут быть агрегированы; если другие значения всегда будут постоянными для заданного значения желаемого элемента группировки, вы можете использовать такую ​​функцию, как MAX. –

+2

То, что вы ищете, не определено. Скажем, у вас есть две строки с одинаковым значением для 'attr1' и разные значения для' attr2'. Что вы хотите, чтобы в результате получился результат? –

ответ

8

Использование аналитических функций 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 

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

+0

Насколько много назад совместимы встроенные функции окна? 11g только? 10г? – MatBailie

+0

Они были введены в 8.x –

+2

+1 Этот метод для «встроенных агрегатов» также применим к PostgreSQL и SQL Server 2005+ – gbn

2

Try:

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 являются постоянными - то есть они функционально зависимы от него.).

+0

'Attr2',' attr3' и т. Д. Не могут быть уникальными. – AppleGrew

+0

@AppleGrew: Этот ответ, похоже, противоречит вашему ответу на комментарий Дейва Коста к вашему вопросу. Что он? –

+0

Этот комментарий был только для 'attr1'. Другие атрибуты могут быть различными или быть не могут. – AppleGrew

1

Из ваших ответов мои комментарии выше, похоже, что вам нужна одна группа за значение 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 от всех присутствующих в группе.

Смежные вопросы