2015-08-20 2 views
0

У меня есть запрос, который использует GROUP BY, поэтому мне нужно поместить выбранные элементы либо в GROUP BY, либо в функцию агрегата. Когда я помещаю их в GROUP BY, t2.category выдает ошибку в заголовке. Я попытался включить агрегатную функцию в операторы CASE/WHEN вместо того, чтобы положить t2.category в GROUP BY, но я получаю ошибку invalid identifier. Примером t2.category может быть «Server Reliability - проблемы с подключением из-за отказа от db». Как я могу избавиться от этой ошибки?ORA-00923: ожидается - получил CLOB

SELECT 
msr._id, 

CASE ans.question_id WHEN '767' THEN ans.category END "767", 
CASE ans.question_id WHEN '768' THEN ans.category END "768" 

FROM table1 t1 
LEFT OUTER JOIN table2 t2 
ON t1._id = t2._id 

WHERE t2.question_id in (767,768) AND t2.assigned_to not in ('Smith, John') 
AND t1.request_type_id in (288,289) and t1.status_id not in (0, 11); 

GROUP BY t1._id, t2.question_id, t2.category 
+0

Я предполагаю, что 't2.category' является' clob' на основе ошибки. Это правильно? –

+0

Да. Это то, что вызывает ошибку. – NoSocks

+0

[Вы не можете группировать по CLOB] (http://docs.oracle.com/cd/E11882_01/appdev.112/e18294/adlob_sql_semantics.htm#ADLOB45594). Вы можете группировать до 4000 символов, но если это было нормально, вам не понадобится CLOB. Почему у вас есть предложение group by, когда у вас нет агрегатов в списке выбора? Это только часть запроса? Если у вас действительно есть агрегаты, покажите репрезентативный запрос и структуры таблицы, и, возможно, есть способ - как присоединение к 't2' после того, как произойдет агрегация. Тем не менее, зависит от ваших данных. –

ответ

2

Другого, чем только с помощью первых 4000 символов значения CLOB, которые, вероятно, не является приемлемым, единственным способом, которым я могу видеть, чтобы обойти restictions на CLOBs (including that you can't group by them), чтобы присоединиться к второй таблице несколько раз:

SELECT 
msr.id, 
ans_767.category AS "767", 
ans_768.category AS "768" 
FROM msr 
LEFT OUTER JOIN ans ans_767 
ON ans_767.id = msr.id 
AND ans_767.question_id = 767 
AND ans_767.assigned_to not in ('Smith, John') 
LEFT OUTER JOIN ans ans_768 
ON ans_768.id = msr.id 
AND ans_768.question_id = 768 
AND ans_768.assigned_to not in ('Smith, John') 
WHERE msr.request_type_id in (288,289) 
AND msr.status_id not in (0, 11); 

     ID 767     768     
---------- -------------------- -------------------- 
     1 back     dev 
     2      dev 

Они оба слева присоединяется, но означает, что вы получите только один ряд назад, поэтому не должны разрушаться значения, полученные из двух строк с вашей версией.

Мне пришлось переместить фильтр question_id в каждый из статей ON; но я также переместил фильтр assigned_to, так как наличие его в предложении where превращает внешние соединения обратно во внутренние соединения.

Это уродливое, но терпимое для двух идентификаторов вопросов, но не очень хорошо масштабируется с точки зрения обслуживания и удобочитаемости.

SQL Fiddle demo, используя значения из предыдущего вопроса; и ваш исходный код (вроде, отредактированный бит) failing.

+0

Это прекрасно. Спасибо! – NoSocks

+1

@NoSocks - если вы все еще хотите обходной путь с первыми 4000 символами, вы должны использовать 'dbms_lob.substr', внутри' MAX() '. [Демо] (http://sqlfiddle.com/#!4/3ba86/6). Если вы используете 11gR2, вы также можете использовать 'pivot' с короткими значениями, что вы делаете вручную. Если вы обрезаете длины категорий, это не так много, если у вас есть столбец CLOB. –

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