#sql #oracle
Вопрос:
Я новичок в SQL и на самом деле не имею большого опыта. Мне нужна помощь в этом, где у меня есть таблица A, и я хочу написать SQL-запрос для получения результата. Любая помощь будет очень признательна! Спасибо!
Таблица А
Имя | Вместимость А | Вместимость B | Емкость C |
---|---|---|---|
Завод 1 | 10 | 20 | |
Завод 2 | 10 |
Таблица Результатов
Имя | Тип | Вместимость |
---|---|---|
Завод 1 | A,C | 10,20 |
Завод 2 | B | 10 |
Я знаю, что функция listagg может объединить несколько столбцов в один, но могу ли я в любом случае создать дополнительный столбец «Тип», где он достаточно умен, чтобы знать, из какого столбца я беру свое значение? Желательно без создания каких-либо дополнительных представлений/таблиц.
Комментарии:
1. Вероятно, вам следует пересмотреть дизайн своего стола.
2. Я хотел бы иметь возможность изменять структуру базы данных. Хаха. В любом случае, спасибо за совет.
3. Пожалуйста, предоставьте достаточно кода, чтобы другие могли лучше понять или воспроизвести проблему.
Ответ №1:
Используйте NVL2
(или CASE
) и объедините столбцы и обрежьте все лишние конечные запятые:
SELECT Name,
RTRIM(
NVL2(CapacityA,'A,',NULL)
||NVL2(CapacityB,'B,',NULL)
||NVL2(CapacityC,'C',NULL),
','
) AS type,
RTRIM(
NVL2(CapacityA,CapacityA||',',NULL)
||NVL2(CapacityB,CapacityB||',',NULL)
||NVL2(CapacityC,CapacityC,NULL),
','
) AS capacity
FROM table_name;
Который, для выборочных данных:
CREATE TABLE table_name (name, capacitya, capacityb, capacityc) AS
SELECT 'Plant1', 10, NULL, 20 FROM DUAL UNION ALL
SELECT 'Plant2', NULL, 10, NULL FROM DUAL;
Выходы:
Имя Тип вместимость Завод1 A,C 10,20 Завод2 B 10
бд<>скрипка <>здесь
Ответ №2:
Вот один из вариантов:
- примеры данных в строках № 1-4
temp
CTE просто — условно — объединяет типы и мощности- последний запрос (строка № 17)
- удаляет двойные разделители (запятые) (регулярное выражение)
- удаляет лишние начальные/конечные запятые (обрезка)
SQL> with test (name, capa, capb, capc) as
2 (select 'Plant1', 10, null, 20 from dual union all
3 select 'Plant2', null, 10, null from dual
4 ),
5 temp as
6 (select name,
7 --
8 case when capa is not null then 'A' end ||','||
9 case when capb is not null then 'B' end ||','||
10 case when capc is not null then 'C' end as type,
11 --
12 case when capa is not null then capa end ||','||
13 case when capb is not null then capb end ||','||
14 case when capc is not null then capc end as capacity
15 from test
16 )
17 select name,
18 trim(both ',' from regexp_replace(type , ', ', ',')) as type,
19 trim(both ',' from regexp_replace(capacity, ', ', ',')) as capacity
20 from temp;
NAME TYPE CAPACITY
------ ---------- ----------
Plant1 A,C 10,20
Plant2 B 10
SQL>
Комментарии:
1. Спасибо тебе за это. Это решение также работает! Но решение другого парня было немного проще, потому что нет необходимости создавать дополнительное временное представление.