SQL | РАЗБИТЬ СТОЛБЦЫ НА СТРОКИ

#oracle #snowflake-cloud-data-platform

#Oracle #snowflake-облачная платформа для обработки данных

Вопрос:

Как я могу разделить данные столбца на строки с помощью basic SQL.

 COL1 COL2
1     A-B
2     C-D
3     AAA-BB
 

Результат

 COL1 Col2
1     A
1     B
2     C
2     D
3     AAA
3     BB
 

Комментарии:

1. Вы используете MySQL или Oracle? (Ответ не подойдет обоим …)

2. Всегда ли это будет первый и третий символ? (Или это может быть ABC-DD?)

3. ORACLE SQL, ЭТО МОЖЕТ БЫТЬ ABC-DD

4. Или это просто обозначается символом a - для обозначения разделений, и у вас может быть A-B-C-D и вам нужно 4 строки?

5. Это довольно неполный вопрос и требует большего контекста. Какую версию SQL вы используете? MS SQL? MySQL или Oracle? @Neel пожалуйста, отредактируйте вопрос и теги, чтобы добавить больше того, что вы просите

Ответ №1:

Начиная с Oracle 12, если это всегда два значения с разделителями, вы можете использовать:

 SELECT t.col1,
       l.col2
FROM   table_name t
       CROSS JOIN LATERAL (
         SELECT SUBSTR(col2, 1, INSTR(col2, '-') - 1) AS col2 FROM DUAL
         UNION ALL
         SELECT SUBSTR(col2, INSTR(col2, '-')   1) FROM DUAL
       ) l
 

Что для образца данных:

 CREATE TABLE table_name (COL1, COL2) AS
SELECT 1, 'A-B' FROM DUAL UNION ALL
SELECT 2, 'C-D' FROM DUAL UNION ALL
SELECT 3, 'AAA-BB' FROM DUAL;
 

Выводит:

COL1 COL2
1 A
1 B
2 C
2 D
3 AAA
3 BB

db<> скрипка здесь

Ответ №2:

Snowflake помечен, так что вот способ снежинки сделать это:

 WITH TEST (col1, col2) as
      (select 1, 'A-B' from dual union all
       select 2, 'C-D' from dual union all
       select 3, 'AAA-BB' from dual
      )
SELECT test.col1, table1.value 
FROM test, LATERAL strtok_split_to_table(test.col2, '-') as table1
ORDER BY test.col1, table1.value;
 

Ответ №3:

Начиная с Oracle:

 SQL> with test (col1, col2) as
  2    (select 1, 'A-B' from dual union all
  3     select 2, 'C-D' from dual union all
  4     select 3, 'AAA-BB' from dual
  5    )
  6  select col1,
  7    regexp_substr(col2, '[^-] ', 1, column_value) col2
  8  from test cross join
  9    table(cast(multiset(select level from dual
 10                        connect by level <= regexp_count(col2, '-')   1
 11                       ) as sys.odcinumberlist))
 12  order by col1, col2;

      COL1 COL2
---------- ------------------------
         1 A
         1 B
         2 C
         2 D
         3 AAA
         3 BB

6 rows selected.

SQL>
 

Ответ №4:

Для MS-SQL 2016 и выше вы можете использовать:

 SELECT Col1, x.value
FROM t CROSS APPLY STRING_SPLIT(t.Col2, '-') as x;
 

Кстати: если Col2 содержит null, он не отображается в результате.