Как добавить декодирование, но также иметь счетчик, группировать и сортировать по - а не по выражению группы - PullRequest
0 голосов
/ 13 сентября 2018

Я довольно новичок в Oracle. Я пытаюсь сделать количество портов для поставщика / модели. Тем не менее, я хочу только те с port_addr_status 3 или 4. По какой-то причине я получаю ошибку

ORA-00979 не группа по выражению

Это то, что я имею до сих пор. Это работает без части декодирования, но я не думаю, что часть с pi.port_addr.status в ('3', '4') работает без нее. Я открыт для работы и над этой проблемой.

select 
   count(pi.port) as cnt, d.VENDOR, trim(d.model) as model, 
   decode(pi.PORT_ADDR_STATUS, '1', 'Unassigned', '2','Pending','3','In Service', 
                               '4','Pending Disco', '5','Trouble', '6','Reserved', 
                               '7','Reserved Capacity', pi.PORT_ADDR_STATUS)
from
   table1 pi,
   table2 d,
   table3 c
where
   pi.id = d.id and
   pi.circuit_id = c.circuit_id 
   and pi.port_addr_status in ('3','4')
   and (d.dslam_type_desc not in ('AGGREGATOR') or d.dslam_type_desc is null)
   and d.DSLAM not like '%@%' 
group by 
       d.VENDOR, d.model --, trim(d.model), pi.RACK, pi.SHELF, pi.SLOT, pi.PORT, pi.BROADBAND_CIRCUIT_ID, d.DSLAM, 
order by
       d.VENDOR asc, cnt desc

Это пример вывода:

1031    Adtran  TA5000
10      Adtran  TA1248V
3       Adtran  TA1248

Ответы [ 3 ]

0 голосов
/ 13 сентября 2018

Причина, по которой вы получаете эту ошибку:

  1. при использовании предложения GROUP BY вы просите СУБД дать вам одну строку, соответствующую вашему списку GROUP BY
  2. в вашем случае вы запрашиваете по одной строке для каждой комбинации (поставщик, модель)
  3. , поскольку каждая из этих строк представляет, возможно, много «базовых» строк (скажем, например, 5 строк для Vendor = A и Model = B)), единственными другими полями, которые вы можете иметь в списке выбора, должны быть агрегаты (поэтому поле «count» работает, оно подсчитывает строки, т. е. может принимать много значений строки и возвращать одно значение)
  4. функция DECODE не является агрегатной функцией - она ​​не может «свернуть» несколько значений в одно значение (например, MAX () может)

Мне кажется, что ваша функция DECODE возвращаетстрок, поэтому я рекомендую вам агрегировать строки с помощью функции LISTAGG (поэтому, если ваши 5 строк имеют значения 'asdf', 'fdsa', 'qwer', 'rewq' и 'zxcv', функция LISTAGG вернет одну строку: 'asdf, fdsa, qwer, rewq, zxcv ')

Таким образом, вы должны заменить свой вызов DECODE (...) на, например, LISTAGG (DECODE (...),', ')

Ссылка для LISTAGGфункция: https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions089.htm#SQLRF30030

0 голосов
/ 18 сентября 2018

Поскольку декодированный тип порта не требуется в выходных данных, просто удалите его из списка выбора.Group By должна включать все в список выбора, кроме агрегатных функций.Приведенный ниже запрос должен выполнить эту работу:

select 
   count(pi.port) as cnt, d.VENDOR, trim(d.model) as model
from
   table1 pi,
   table2 d,
   table3 c
where
   pi.id = d.id and
   pi.circuit_id = c.circuit_id 
   and pi.port_addr_status in ('3','4')
   and (d.dslam_type_desc not in ('AGGREGATOR') or d.dslam_type_desc is null)
   and d.DSLAM not like '%@%' 
group by 
       d.VENDOR, trim(d.model)
order by
       d.VENDOR asc, cnt desc

Обратите внимание, что здесь достигается фильтрация до определенных типов портов:

and pi.port_addr_status in ('3','4')

в предложении where - оператор декодирования в вашем оригиналезапрос ничего не сделал для решения ваших требований и был прямой причиной ошибки.В базовом агрегированном запросе, подобном следующему, в group by должен быть каждый элемент в списке выбора, который не является агрегирующей функцией.

0 голосов
/ 13 сентября 2018

Вы можете использовать оператор decode в списке выбора с функцией агрегирования, предпочтительно max как

max( decode(pi.PORT_ADDR_STATUS, '1', 'Unassigned', '2','Pending', .... )

...