#sql #oracle
#sql #Oracle
Вопрос:
У меня есть следующая таблица :
Таблица 1
Create table Table1 (Col1 Varchar2(50) not null, Col2 Varchar2(50), Col3 Varchar2(50));
Insert into Table1 (col1, col2, col3) values
('RED','aa','11,22,33'),
('Green','bb','33'),
('blue','bb','11,44'),
('yellow','bb','55,66'),
('orange','bb','22,33');
Colx_11 будет иметь значение, основанное на Table1, сколько записей в Table1 для Col3 имеет значение 11 в качестве значения.
Аналогично для 22,33 и других значений.
Комментарии:
1. Требуется sql-запрос для получения выходных данных, показанных в Table2
2. почему это помечено как oracle ? mysql и oracle 2 разные базы данных
3. @KoenLostrie Спасибо, это было по ошибке. Сейчас я это исправил.
4. Может ли столбец
Col3
содержать одно и то же число дважды? Например11,11,22
. Если да, вы считаете11
дважды или один раз?5. Нет дубликатов в том же столбце.
Ответ №1:
Поскольку версия oracle неизвестна, я бы поставил свой ответ со всеми возможностями,
Поскольку в oracle нет конкретной предопределенной функции, доступной для простого разделения записей, разделенных запятыми, нам нужно использовать regular expression
ее для разделения, а затем подсчитать вхождение.
Использование условной агрегации (работа с любой версией> 8i):
select sum(case when split_number = 11 then 1 else 0 end) as col_11
,sum(case when split_number = 22 then 1 else 0 end) as col_22
,sum(case when split_number = 33 then 1 else 0 end) as col_33
,sum(case when split_number = 44 then 1 else 0 end) as col_44
,sum(case when split_number = 55 then 1 else 0 end) as col_55
,sum(case when split_number = 66 then 1 else 0 end) as col_66
from table1 t1
join (select distinct col3,regexp_substr(col3,'[^,] ', 1, level) split_number
from table1 t2
connect by regexp_substr(col3, '[^,] ', 1, level) is not null) t2
on t2.col3 = t1.col3;
Использование PIVOT и JOIN (работа с любой версией> = 11g):
select *
from
(
select split_number
from table1 t1
join (select distinct col3,regexp_substr(col3,'[^,] ', 1, level) split_number
from table1 t2
connect by regexp_substr(col3, '[^,] ', 1, level) is not null) t2
on t2.col3 = t1.col3
)
pivot
(
count(*)
for split_number in ( 11 as col_11
, 22 as col_22
, 33 as col_33
, 44 as col_44
, 55 as col_55
, 66 as col_66)
);
Использование PIVOT и LATERAL (работа с любой версией> = 12c):
select *
from
(
select split_number
from table1 t1,
lateral (select regexp_substr(col3,'[^,] ', 1, level) split_number
from dual
connect by regexp_substr(col3, '[^,] ', 1, level) is not null) t2
)
pivot
(
count(*)
for split_number in ( 11 as col_11
, 22 as col_22
, 33 as col_33
, 44 as col_44
, 55 as col_55
, 66 as col_66)
);
Я все же хотел бы упомянуть здесь, что недостатком приведенных выше запросов является явное упоминание столбцов типа col_11
и col_22
… и т.д., и для этой динамики нам понадобится динамический SQL или что-нибудь с XML
запросами.