2013-12-19 4 views
6

Я пытаюсь объединить функцию GROUP BY с MAX в оракуле. Я читал много документации вокруг, попытаться выяснить, как форматировать мой запрос, Oracle всегда возвращается:Как использовать GROUP BY в столбце CLOB с Oracle?

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

Вот мой запрос:

SELECT A.T_ID, B.T, MAX(A.V) 
FROM bdd.LOG A, bdd.T_B B 
WHERE B.T_ID = A.T_ID 
GROUP BY A.T_ID 
HAVING MAX(A.V) < '1.00'; 

Любые советы?

EDIT Кажется, у вас есть какая-то сложная часть с типом данных моих полей.

  • T_ID является VARCHAR2
  • A.V является VARCHAR2
  • B.T является CLOB
+3

Не сравнивать яблоки (цифры) с апельсинами (струнами). '' 1.00'' - это строка *** *** *** число - ('1.00' или' 1') - это число. –

+0

@a_horse_with_no_name Вы правы, теперь это лучше :) Но у меня все еще есть ошибка 932, посмотрите, что slay oracle ожидал некоторый тип данных и получил CLOB insteab - который является типом BT – Xavier

+0

Вы не можете делать 'group by' в столбце 'CLOB' - зачем вам это вообще нужно? Если вам нужен max(), тогда 'CLOB' не похож на правильный тип данных. И если вы храните номера в 'LOG.V', то почему бы вам не определить его как' number' ?. Это очень плохой дизайн для хранения чисел в столбцах «varchar». –

ответ

1

После некоторых исправлений, кажется, что главная проблема была в group by

вы должны использовать те же таблицы в SELECT и в GROUP BY

Я также беру только подстроку CLOB, чтобы получить оно работает. Рабочие запрос:

SELECT TABLE_A.ID, 
     TABLE_A.VA, 
     B.TRACE 
FROM 
(SELECT A.T_ID ID, 
      MAX(A.V) VA 
    FROM BDD.LOG A 
    GROUP BY A.T_ID HAVING MAX(A.V) <= '1.00') TABLE_A, 
                   BDD.T B 
WHERE TABLE_A.ID = B.T_id; 
1

Попробуйте это:

SELECT A.T_ID, B.T, MAX(A.V) 
FROM bdd.LOG A, bdd.T_B B 
WHERE B.T_ID = A.T_ID 
GROUP BY A.T_ID, B.T 
HAVING MAX(A.V) < 1; 
+0

Он возвращает другую ошибку: ORA-00932 непоследовательные типы данных. Это относится к комментарию выше? – Xavier

+0

@x_vi_r Да, должно быть. Я обновил ответ, проверив его –

+0

По-прежнему получаю ошибку 932, так как я сказал выше, A.V - это VARCHAR2 – Xavier

0
WITH foo as (
    SELECT A.T_ID, B.T, MAX(A.V) maxav 
    FROM bdd.LOG A, bdd.T_B B 
    WHERE B.T_ID = A.T_ID 
    GROUP BY A.T_ID, B.T 
) 
SELECT * FROM foo WHERE maxav < 1 
+0

Thx для помощи! Такая же ошибка, как и раньше: ORA-00932 ожидаемый тип данных: - получил CLOB. (CLoB - тип данных B.T) – Xavier

+0

Тогда, очевидно, группировка по столбцу CLOB является плохой идеей. –

+0

Должен ли я использовать DBMS_LOB? – Xavier

11

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

GROUP BY TO_CHAR(theclob) 

, а затем, конечно, вы должны TO_CHAR в CLOB в своих выходах тоже.

Обратите внимание, что существует 2 уровня этой проблемы ... во-первых, у вас есть столбец clob, который не должен быть clob; он содержит только несколько небольших строк, которые бы вписывались в VARCHAR2. Мое обходное решение относится к этому.

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

0

Этот ответ немного поздний, но для тех, кто нуждается в значении, кроме значения группирования и максимального столбца критериев, вы можете использовать ROW_NUMBER() над перегородкой, чтобы получить то, что вы хотите:

SELECT T_ID, T, V 
FROM 
(
SELECT A.T_ID, B.T, A.V, ROW_NUMBER() OVER (PARTITION BY A.T_ID ORDER BY to_number(A.V) DESC) rownumber 
FROM bdd.LOG A, bdd.T_B B 
WHERE B.T_ID = A.T_ID 
) 
WHERE rownumber = 1 

Не забудьте модификатор DESC на ORDER BY, чтобы получить максимальное значение; без него вы получите Минимальное значение. Если.V является нулевым, вам также нужно будет обернуть его в NVL(), или вы просто получите NULL; Значения NULL всегда сортируют сначала (по крайней мере, в Oracle SQL) независимо от того, выбираете ли вы восходящий или нисходящий порядок.

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