Преобразование данных из строк в столбцы. У меня есть две строки ID
и одна строка текста VARCHAR2
. Но один из рядов ID
не всегда одинаков. Иногда отсутствуют данные.
Я пробовал с PIVOT
и GROUP BY
до сих пор это дало мне только ошибки.
SELECT prj_id, udn_id, txt_value
FROM TBL
GROUP BY tbl.prj_id;
Я хотел бы преобразовать это: (пустая строка только для лучшей видимости)
PRJ_ID UDN_ID TXT_ VALUE
8344 82 13/10/2009
8344 64 E S
8344 178 End
8364 82 12/10/2009
8364 64 A M
8364 89 M
8364 178 Internal
8335 82 05/10/2009
8335 64 E S
8335 89 N
8335 178 End
8377 82 13/10/2009
8377 64 Z D
8377 89 N;M
8377 178 Internal
к этому:
82 64 89 178
8344 13/10/2009 E S N/A End
8364 12/10/2009 A M M Internal
8335 05/10/2009 E S N End
8377 13/10/2009 Z D N;M Internal
Любая идея, как решить это с помощью SQL?
Я новичок в синтаксисе Oracle. Итак, я написал в синтаксисе SQL-сервера. Надеюсь, это поможет вам:
CREATE TABLE Project(PRJ_ID int, UDN_ID INT, TXT_VALUE varchar(100));
INSERT INTO Project VALUES (8344,82,'E S'),(8344,69,'A M'),(8364,82,'End'),(8364,59,'Internal');
DECLARE @columns NVARCHAR(MAX), @columns1 NVARCHAR(MAX), @sql NVARCHAR(MAX);
--selecting distinct values and concatenating to get a result like [82],[69],[82]...
SELECT @columns1 = STUFF((
SELECT DISTINCT ',' + '['+ CAST(UDN_ID AS VARCHAR) + ']' FROM Project
FOR XML PATH('')
), 1, 1, '')
FROM Project;
--using that dynamic column string in the pivot query string
SET @sql = 'SELECT PRJ_ID,' + @columns1 + ' FROM
(
SELECT * FROM Project
) AS src
PIVOT
(
MAX(TXT_VALUE) FOR src.UDN_ID IN ('+ @columns1
+ ')
) AS p;';
--executing the pivot query
EXEC sp_executesql @sql;
Это не подходящий ответ для Oracle.
Спасибо, Гордон. сейчас изменит синтаксис.
Я изо всех сил старался изменить синтаксис на Oracle. Но это было очень исчерпывающе. улучшит это позже Гордон. В любом случае, спасибо, что указали.
Это достижимо с помощью PIVOT в оракуле. Пожалуйста, используйте ниже и дайте мне знать в случае каких-либо вопросов.
select * from (
with all_data as(
select '8344' prj_id, 82 id, '40099' txt_val from dual union all
select '8344' prj_id, 64 id, 'E S' txt_val from dual union all
select '8344' prj_id, 178 id, 'End' txt_val from dual union all
select '8364' prj_id, 82 id, '40098' txt_val from dual union all
select '8364' prj_id, 64 id, 'A M' txt_val from dual union all
select '8364' prj_id, 89 id, 'M' txt_val from dual union all
select '8364' prj_id, 178 id, 'Internal' txt_val from dual union all
select '8335' prj_id, 82 id, '40091' txt_val from dual union all
select '8335' prj_id, 64 id, 'E S' txt_val from dual union all
select '8335' prj_id, 89 id, 'N' txt_val from dual union all
select '8335' prj_id, 178 id, 'End' txt_val from dual union all
select '8377' prj_id, 82 id, '40099' txt_val from dual union all
select '8377' prj_id, 64 id, 'Z D' txt_val from dual union all
select '8377' prj_id, 89 id, 'N;M' txt_val from dual union all
select '8377' prj_id, 178 id, 'Internal' txt_val from dual)
select prj_id,id,txt_val from all_data)
pivot
(max(txt_val)
for id in (82 as "82_val", 64 as "64_val", 89 as "89_val", 178 as "178_val"))
order by 1
;
У меня более 3 миллионов строк, так что это не разумный метод. :-(
Итак, значения в для необходимо сделать как динамический sql. исправленный синтаксис по первому ответу Шабари должен работать на вас.
Способ старомодный (до PIVOT
) заключался в агрегировании значения с использованием DECODE
(или CASE
, для лучшей читабельности). Вот пример (строки 16 и далее - это то, что вы ищете):
SQL> with tbl (prj_id, udn_id, txt_value) as
2 (select 8344, 82, '13/10/2009' from dual union all
3 select 8344, 64, 'E S' from dual union all
4 select 8344, 178, 'End' from dual union all
5 --
6 select 8364, 82, '12/10/2009' from dual union all
7 select 8364, 64, 'A M' from dual union all
8 select 8364, 89, 'M' from dual union all
9 select 8364, 178, 'Internal' from dual union all
10 --
11 select 8335, 82, '05/10/2009' from dual union all
12 select 8335, 64, 'E S' from dual union all
13 select 8335, 89, 'N' from dual union all
14 select 8335, 178, 'End' from dual
15 )
16 select prj_id,
17 max(case when udn_id = 82 then txt_value end) "82",
18 max(case when udn_id = 64 then txt_Value end) "64",
19 max(case when udn_id = 89 then txt_value end) "89",
20 max(case when udn_id = 178 then txt_Value end) "178"
21 from tbl
22 group by prj_id;
PRJ_ID 82 64 89 178
---------- ---------- ---------- ---------- ----------
8335 05/10/2009 E S N End
8344 13/10/2009 E S End
8364 12/10/2009 A M M Internal
SQL>
Начальная таблица имеет 3 миллиона строк.