根据ID将一行拆分为两行

时间:2015-09-15 16:44:31

标签: sql oracle

我正在查询一个数据库,该数据库在一个Column-ID中用逗号分隔两个ID

table:user

B_ID   FirstName   LastName  email
B5,B6  Mo         Asif     xxx
B1     Adam      chung     xxx

由于Mo有两个ID:B5,B6 - 如何查询数据库,以便将它们拆分为两个单独的行, - 正好像这样

B_ID   FirstName   LastName  email
B5      Mo         Asif     xxx
B6      Mo         Asif     xxx
B1      Adam       chung    xxx

有些情况下有3个ID,但我想要3,4..IDs的相同结果

3 个答案:

答案 0 :(得分:1)

这将处理与B_ID和NULL B_ID元素一样多的B_ID。始终测试意外的值/条件,并确保您正在处理它们!我建议重命名B_ID列。该名称意味着一个唯一的标识符,它显然不是。要么需要那个,要么进一步标准化。

请注意处理NULL列表元素的正则表达式。 The commonly used expression of '[^,]+' for parsing lists does not handle NULL elements

SQL> with tbl(B_ID, FirstName, LastName, email) as (
     select 'B5,B6',  'Mo',    'Asif',  'xxx@yxz.com' from dual
     union
     select 'B1',     'Adam',  'chung', 'xxx@xyz.com' from dual
     union
     select 'B7,,B9', 'Lance', 'Link',  'llink@ape.org'     from dual
     union
     select '',       'Mata',  'Hari',  'mhari@ape.org'     from dual
   )
    SELECT REGEXP_SUBSTR(B_ID , '(.*?)(,|$)', 1, COLUMN_VALUE, NULL, 1 ) AS B_ID,
          firstname, lastname, email
    FROM   tbl,
          TABLE(
            CAST(
              MULTISET(
                SELECT LEVEL
                FROM   DUAL
                  CONNECT BY LEVEL <= REGEXP_COUNT(B_ID , ',' )+1
              ) AS SYS.ODCINUMBERLIST
            )
          );

B_ID   FIRST LASTN EMAIL
------ ----- ----- -----------
B1     Adam  chung xxx@xyz.com
B5     Mo    Asif  xxx@yxz.com
B6     Mo    Asif  xxx@yxz.com
B7     Lance Link  llink@ape.org
       Lance Link  llink@ape.org
B9     Lance Link  llink@ape.org
       Mata  Hari  mhari@ape.org

7 rows selected.

SQL>

答案 1 :(得分:0)

WITH cte AS
      (SELECT B_ID,FirstName,LastName,email  FROM t)
SELECT  REGEXP_SUBSTR(t1.B_ID, '([^,])+', 1, t2.COLUMN_VALUE),FirstName,LastName,email
FROM cte t1 CROSS JOIN
            TABLE
            (
                CAST
                (
                    MULTISET
                    (
                        SELECT LEVEL
                        FROM DUAL 
                        CONNECT BY LEVEL <= REGEXP_COUNT(t1.B_ID, '([^,])+')
                    )
                    AS SYS.odciNumberList
                )
            ) t2;

FIDDLE

答案 2 :(得分:0)

Simple Union,substr和insert应该可以解决你的问题。

mysql> select substr('B5,B6',instr('B5,B6',',')-2,2) as a from dual
    -> UNION
    -> select substr('B5,B6',instr('B5,B6',',')+1,2) as a from dual;

输出:

+----+
| a  |
+----+
| B5 |
| B6 |
+----+
2 rows in set (0.06 sec)

希望它可以帮助你:)