#sql #oracle #oracle11g
#sql #Oracle #oracle11g
Вопрос:
Я пытаюсь отобразить строки таблицы в виде столбцов, это обычный вывод:
ITEM | CODE | SET | CREATION | CATEGORY | GROUP
1 1 CP 06/11/2020 10 52
2 3 PN 07/11/2020 9 57
3 1 PNI 08/11/2020 12 53
Вот как мне нужно это отобразить:
ITEM | 1 | 2 | 3
CODE | 1 | 3 | 1
SET | CP | PN | PNI
CREATION | 06/11/2020 | 07/11/2020 | 08/11/2020
CATEGORY | 10 | 9 | 12
GROUP | 52 | 57 | 53
Я совсем новичок в SQL, я пытался использовать функцию Oracle pivot, но я не получаю желаемого результата, возможно ли это вообще? Есть предложения?
Комментарии:
1. Известно ли заранее количество «элементов»? Если нет, вам понадобится динамический SQL — это продвинутая тема, и начинать с нее не рекомендуется.
Ответ №1:
Вероятно, самый простой метод union all
. Предполагая, что все столбцы являются строками:
with t as (
select t.*, row_number() over (order by item) as seqnum
from yourtable
)
select 'item',
max(case when seqnum = 1 then item end),
max(case when seqnum = 2 then item end),
max(case when seqnum = 3 then item end)
from t
union all
select 'code',
max(case when seqnum = 1 then code end),
max(case when seqnum = 2 then code end),
max(case when seqnum = 3 then code end)
from t
union all
select 'set',
max(case when seqnum = 1 then set end),
max(case when seqnum = 2 then set end),
max(case when seqnum = 3 then set end)
from t
union all
-- and so on for the rest of the columns
Ответ №2:
Транспонирование означает открепление, затем поворот (по разным измерениям).
При отключении вы объединяете значения разных типов данных в одном столбце (промежуточного) результирующего набора. Это не может работать; вы должны сначала преобразовать все в строки. (Это означает, что если у вас есть данные, которые нельзя преобразовать в строки, весь проект завершится неудачей.) Обратите внимание, что для простоты я установил NLS_DATE_FORMAT
значение 'dd/mm/yyyy'
; в производственном коде вы должны указать явную модель формата при TO_CHAR
вызове дат.
Кроме того, вам необходимо заранее знать количество входных строк (элементов) — в противном случае вы должны использовать динамический SQL, который не является темой начального уровня — и в любом случае не является хорошей практикой.
Вот как это происходит. Обратите внимание, что я изменил два имени столбцов ( SET
и GROUP
являются зарезервированными ключевыми словами в Oracle, они не могут быть именами столбцов) в образце данных, который я включил в WITH
предложение. Конечно, WITH
предложение не является частью решения — оно существует только для тестирования.
Я также использовал расширенную функцию UNPIVOT
, чтобы создать столбец для упорядочения в конце. Это не критично — вы можете использовать более элементарную версию UNPIVOT
и использовать другой подход для получения выходных данных в правильном порядке.
with
sample_data (ITEM, CODE, set_, creation, category, group_) as (
select 1, 1, 'CP' , to_date('06/11/2020'), 10, 52 from dual union all
select 2, 3, 'PN' , to_date('07/11/2020'), 9, 57 from dual union all
select 3, 1, 'PNI', to_date('08/11/2020'), 12, 53 from dual
)
select col, "1", "2", "3"
from (
select to_char(item) as item, to_char(code) as code, set_,
to_char(creation) as creation, to_char(category) as category,
to_char(group_) as group_, rownum as rn
from sample_data
)
unpivot (value for (col, ord) in (item as ('ITEM', 1), code as ('CODE', 2),
set_ as ('SET', 3), creation as ('CREATION', 4),
category as ('CATEGORY', 5), group_ as ('GROUP', 6)))
pivot (min(value) for rn in (1, 2, 3))
order by ord
;
COL 1 2 3
-------- -------------------- -------------------- --------------------
ITEM 1 2 3
CODE 1 3 1
SET CP PN PNI
CREATION 06/11/2020 07/11/2020 08/11/2020
CATEGORY 10 9 12
GROUP 52 57 53