#sql #oracle #pivot
Вопрос:
Я пытаюсь выполнить простой запрос в Oracle SQL с помощью Pivot. В моей таблице 12 столбцов, но интерес представляют только первые четыре. Столбцами являются «FACILITY_ID» (уникальный идентификатор), «REPORTING_YEAR» (были сообщены данные за год), «ПОДРАЗДЕЛ» (Категория данных, которые хотят пересчитать по значениям, приемлемым между А и Я) и «CO2E» (число с плавающей запятой). Я хочу взять только данные из подразделов C и K (третий столбец) и добавить их в свои собственные столбцы.
Например:
Если моя исходная таблица выглядит так:
FACILITY_ID --- REPORTING_YEAR --- SUBPART --- CO2E
10 -------------- 2020 ---------------------- C -------- 10
11 -------------- 2020 ---------------------- K -------- 20
10 -------------- 2020 ---------------------- K -------- 40
10 -------------- 2020 ---------------------- K -------- 40
11 -------------- 2020 ---------------------- C -------- 30
Я хотел бы получить что-то вроде:
FACILITY_ID --- REPORTING_YEAR ----- C ----- K
10 -------------- 2020 ----------------- 10 ----- 80
11 -------------- 2020 ----------------- 30 ----- 20
Мой код на данный момент выглядит следующим образом:
Create Table CandK_emissions as
Select
FACILITY_ID,
REPORTING_YEAR,
SUBPART,
CO2E
From
facilityReport
Pivot
(
Sum(CO2E)
For SUBPART
in ('C',
'K')
)
Я получаю ошибку «Ora-00904:» CO2e»: Неверный идентификатор». Я дважды проверил, все ли написано правильно. Я не уверен, где я ошибаюсь.
Комментарии:
1. Удалено, спасибо @jarlh
2. Что — то не так. В других местах вы показываете либо CO2E (не в двойных кавычках, поэтому капитализация не имеет значения), либо «CO2E» во всех заглавных буквах и в двойных кавычках (что делает имя чувствительным к регистру). Но в сообщении об ошибке жалуется на «CO2e» со строчной буквой «e», это может быть проблемой, но вы сказали: «вы проверили, что все написано правильно». Я не думаю, что Oracle меняет E на e самостоятельно, даже для того, чтобы показать это в сообщении об ошибке. Возможно, вы недостаточно тщательно проверили?
3. После того как вы преодолеете эту проблему, вы можете обнаружить, что ваш запрос на самом деле не работает. PIVOT предполагает, что данные должны быть сгруппированы по всем столбцам, на которые нет ссылок в предложении PIVOT; поэтому, если вы должны игнорировать некоторые другие столбцы для «группировки», вы не должны выбирать (а затем сводить) из всей таблицы, а из встроенного подзапроса, в котором вы выбираете только соответствующие столбцы, образующие базовую таблицу.
4. @mathguy вы можете игнорировать заглавную букву. Все это прописано в моем настоящем Оракуле. Я просто перепечатал и слегка изменил имена, потому что не смог скопировать и вставить их по причинам VDI. Я попробую либо сначала выбрать четыре столбца и составить таблицу, либо изменить свой запрос. Я очень новичок во всем этом
5. Хорошо, извините — теперь я вижу проблему. В вашем текущем запросе (независимо от того, будет ли он в конечном итоге делать то, что вам нужно, или нет), вы сводите СУММУ(CO2E) для (….). После поворота в результате нет столбца CO2E; сумма CO2E появится либо в столбце C, либо в столбце K. Итак, что делает CO2E в предложении SELECT? Вот что вызывает эту ошибку. То же самое с ПОДРАЗДЕЛОМ. Вместо этого вам следует выбрать C и K. Предложение SELECT должно отображать столбцы, которые будут отображаться в выходных данных (а не столбцы, существующие во входной таблице).
Ответ №1:
SELECT
Предложение должно показывать, какие столбцы будут существовать в выходных данных, а не какие столбцы используются из базовой таблицы. В своем запросе вы агрегируете значения CO2E отдельно для разных значений ПОДРАЗДЕЛА. Результат поворота больше не содержит значений CO2E или значений ПОДРАЗДЕЛОВ; вместо этого два значения подразделов, которые вас интересуют, C и K, становятся двумя отдельными столбцами в выходных данных, и суммы CO2E отображаются в этих двух новых столбцах.
В вашем запросе должны быть ВЫБРАНЫ столбцы C и K; сообщение об ошибке сообщает вам, что после поворота нет столбца CO2E для выбора. (После того, как вы измените это, это скажет вам то же самое о ПОДРАЗДЕЛЕ.)
Вот как это должно выглядеть. Обратите внимание на несколько вещей: В разделе «тестовые данные» я смоделировал еще один столбец, первичный ключ с именем PK, чтобы продемонстрировать, что вы должны сначала ИСКЛЮЧИТЬ его во встроенном представлении (дополнительный ВЫБОР в предложении FROM). Также обратите внимание, что, чтобы сделать СВОДКУ как можно более эффективной, в подзапросе я выбираю только те строки, которые нам нужны, — те, в которых подраздел либо C, либо K. Нам не нужно видеть другие строки.
Предложение WITH предназначено только для тестирования — удалите его и используйте в запросе свои фактические имена таблиц и столбцов.
with
test_data (pk, facility_id, reporting_year, subpart, co2e) as (
select 335, 10, 2020, 'C', 10 from dual union all
select 440, 11, 2020, 'K', 20 from dual union all
select 482, 10, 2020, 'K', 40 from dual union all
select 106, 10, 2020, 'K', 40 from dual union all
select 476, 11, 2020, 'C', 30 from dual
)
-- end of test data; actual query begins below this line
select facility_id, reporting_year, c, k
from (
select facility_id, reporting_year, subpart, co2e
from test_data
where subpart in ('C', 'K')
)
pivot (sum(co2e) for subpart in ('C' as c, 'K' as k))
order by facility_id, reporting_year -- or whatever is needed
;
FACILITY_ID REPORTING_YEAR C K
----------- -------------- ---------- ----------
10 2020 10 80
11 2020 30 20
Примечание — может быть проще (и эффективнее) вообще отказаться от ПОВОРОТА и «повернуть» по-старому, используя условную агрегацию (способ поворота выполнялся до введения оператора ПОВОРОТА). Что-то вроде этого:
select facility_id, reporting_year,
sum(case subpart when 'C' then co2e end) as c,
sum(case subpart when 'K' then co2e end) as k
from test_data
group by facility_id, reporting_year
order by facility_id, reporting_year
;
Комментарии:
1. Привет, спасибо за это. Это полезно знать, двигаясь вперед — мне нравится более простой метод без поворота. Я постараюсь придерживаться этого в будущем