ORA-00920: недопустимый реляционный оператор при использовании оператора IN - PullRequest
1 голос
/ 20 октября 2019

У меня есть таблица col, где у меня есть:

select * from offc.col;

enter image description here

Я вернул некоторые данные, используя запрос по годам и dept_id мудрый:

 SELECT dept_id, 
       year, 
       Max(marks) marks 
FROM   offc.col 
GROUP  BY dept_id, 
          year 
ORDER  BY dept_id, 
          year 

Данные, которые я получил, были:

enter image description here

Здесь нет проблем, так как мой sql работает правильно. Мне нужно было извлечь всю информацию из таблицы col, поэтому я использовал подзапрос как:

SELECT * 
FROM   offc.col 
WHERE  ( dept_id, year, marks ) IN (SELECT dept_id, 
                                           year, 
                                           Max(marks) marks 
                                    FROM   offc.col 
                                    GROUP  BY dept_id, 
                                              year 
                                    ORDER  BY dept_id, 
                                              year); 

Но я получил ошибку как:

ORA-00920: invalid relational operator 

Я искал эту ошибку вдругие страницы также, но я нашел их в качестве ошибки в скобках. Но в моем случае я не знаю, что здесь происходит?

Ответы [ 3 ]

2 голосов
/ 20 октября 2019

Я бы предложил использовать аналитическую функцию dense_rank, поскольку она может возвращать два отдела, если они имеют одинаковые оценки в одном и том же году. (Ваша текущая логика такая же, как эта)

Row_number даст вам толькоодна случайная запись, если два отдела имеют одинаковые отметки в одном и том же году.

select *
from (
    select 
        c.*, 
        dense_rank() over(partition by dept_id, year order by marks desc nulls last) as dr
    from offc.col c
) x
where dr = 1
order by dept_id, year 

Кроме того, ваш запрос верный, просто удалите из него заказ по.

SELECT * 
FROM   offc.col 
WHERE  ( dept_id, year, marks ) IN (SELECT dept_id, 
                                           year, 
                                           Max(marks) marks 
                                    FROM   offc.col 
                                    GROUP  BY dept_id, 
                                              year 
                                    -- ORDER  BY dept_id,                                              
                                -- year
); 

Демо ошибка с order by и работает нормально без order by.

Ура !!

1 голос
/ 20 октября 2019

Вместо агрегирования вы можете фильтровать с помощью коррелированного подзапроса:

select c.*
from offc.col c
where marks = (
    select max(marks)
    from offc.col c1
    where c1.dept_id = c.dept_id and c1.year = c.year
)
order by dept_id, year 

Индекс на (dept_id, year, marks) ускорит этот запрос.

Другой вариант - использовать оконную функцию row_number():

select *
from (
    select 
        c.*, 
        row_number() over(partition by dept_id, year order by marks desc) rn
    from offc.col c
) x
where rn = 1
order by dept_id, year 

Если вы хотите, чтобы придерживался агрегации, вы можете объединить свой подзапрос с исходной таблицей следующим образом:

select c.* 
from offc.col c
inner join (
    select dept_id, year, max(marks) marks 
    from offc.col 
    group  by dept_id, year 
) m 
    on m.dpt_id = c.dept_id
    and m.year = c.year
    and m.marks = m.marks
0 голосов
/ 20 октября 2019

Выполните INNER JOIN с вашим подзапросом:

SELECT c.*
  FROM offc.col c
  INNER JOIN (SELECT dept_id, 
                     year, 
                     Max(marks) AS MAX_MARK
                FROM offc.col 
                GROUP BY dept_id, 
                         year) s
    ON s.DEPT_ID = c.DEPT_ID AND
       s.YEAR = c.YEAR AND
       s.MAX_MARK = c.MARKS
  ORDER BY c.DEPT_ID, c.YEAR

INNER JOIN возвращает только те строки, для которых выполнено условие соединения, поэтому любые строки в OFFC.COL, которые не имеют максимального значения MARKS дляконкретные DEPT_ID и YEAR не будут возвращены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...