#oracle
#Oracle
Вопрос:
Я искал на форуме, прежде чем публиковать это, и нашел несколько тем, которые были близки к той же проблеме, но у меня все еще были вопросы, поэтому я публикую их здесь.
EMP_ID SEQ_NR NAME
874830 3 JOHN
874830 4 JOE
874830 21 MIKE
874830 22 BILL
874830 23 ROBERT
874830 24 STEVE
874830 25 JERRY
Мой вывод должен выглядеть следующим образом.
EMP ID SEQ3NAME SEQ4NAME SEQ21NAME SEQ22NAME SEQ23NAME SEQ24NAME SEQ25NAME
874830 JOHN JOE MIKE BILL ROBERT STEVE JERRY
SELECT A.EMP_ID
,A.NAME SEQ3NAME
,B.NAME SEQ4NAME
FROM AC_XXXX_CONTACT A
INNER JOIN AC_XXXX_CONTACT B ON A.EMP_ID = B.EMP_ID
WHERE A.SEQ_NR = '03' AND B.SEQ_NR = '04'
AND B.EMP_ID = '874830';
Приведенный выше запрос помог мне получить следующие результаты.
EMP_ID SEQ3NAME SEQ4NAME
874830 JOHN JOE
Мой вопрос заключается в том, чтобы получить все поля (т.Е. до seq nr = 25), если я присоединюсь к таблице еще 5 раз.
Есть ли лучший способ получить результаты?
Я выполняю запросы к базе данных Oracle
Спасибо за вашу помощь.
Новое требование
New Input
STU-ID SEM CRS-NBR
12345 1 100
12345 1 110
12345 2 200
New Output
stu-id crs1 crs2
12345 100 200
12345 110
Комментарии:
1. У вас есть фиксированный список возможных значений SEQ_NR, которые все известны заранее? Если нет, то то, что вы хотите, невозможно в обычном SQL; вам нужен «динамический SQL», что по сути означает, что вам нужно прочитать таблицу в одном запросе, выводом которого является текст нового запроса, который сгенерирует желаемый результат. Проблема в том, что SQL-запрос должен заранее знать количество и имена (и типы данных) всех столбцов, включенных в выходные данные.
2. Да, SEQ_NR будет иметь только указанные выше значения.
3. Какая версия Oracle? Вам нужен поворот, и самое простое решение зависит от вашей версии Oracle. Однако ни в одной версии объединения не требуются.
Ответ №1:
Не проверено, поскольку вы не предоставили тестовые данные (из таблицы AC_XXXX
):
(используя сводное предложение Oracle 11)
select *
from ( select emp_id, seq_nr, name
from ac_xxxx
where emp_id = '874830' )
pivot ( max(name) for seq_nr in (3 as seq3name, 4 as seq4name, 21 as seq21name,
22 as seq22name, 23 as seq23name, 24 as seq24name, 25 as seq25name)
)
;
Для Oracle 10 или более ранних версий поворот выполнялся «вручную», например:
select max(emp_id) as emp_id, -- Corrected based on comment from OP
max(case when seq_nr = 3 then name end) as seq3name,
max(case when seq_nr = 4 then name end) as seq4name,
-- etc. (similar expressions for the other seq_nr)
from ac_xxxx
where emp_id = '874830'
;
Или, emp_id
не обязательно должно быть внутри max()
, если мы добавим group by emp_id
— что тогда будет работать даже без предложения WHERE, для другого, но связанного вопроса.
Комментарии:
1. Спасибо mathguy. Это сработало. Я поддержал ответ, но в нем говорилось, что мой голос был записан, но поскольку моя репутация меньше 15, публично отображаемая оценка публикации не изменяется.
2. @Cyber_Knight — Не беспокойтесь, меня действительно не волнует репутация, и я считаю, что такие места могут быть даже лучше без «репутации» (но другие не согласны).
3. Здравствуйте, не могли бы вы также дать мне решение без использования pivot?
4. Решение выполняется независимо от поворота, но оператор «PIVOT» не существовал в Oracle 10 и более ранних версиях. Я добавлю к своему ответу, чтобы показать, как это было сделано до Oracle 11.
5. @mathguy.. Большое вам спасибо. Это сработало, но мне пришлось использовать GROUP BY EMP_ID, поскольку я был ORA-00937: не одногруппная групповая функция