Oracle SQL: Объединение нескольких столбцов в 1 с условиями

#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. Спасибо тебе за это. Это решение также работает! Но решение другого парня было немного проще, потому что нет необходимости создавать дополнительное временное представление.