如何使用 oracle 根据要求拆分给定的字符串
How to split the given string as per requirement using oracle
我需要拆分名称以插入数据库。下面给出了一些示例字符串。
Covey, Stephen J, Mr
Clinton, Hilary B,
Obama, Barack, Mr
我需要像下面这样拆分上面的字符串。
First_Name Middle_Initial Last_NAME Title
Stephen J Covey Mr
Hilary B Clinton
Barack Obama Mr
我可以使用 java 代码实现上述目标。是否可以将这些字符串直接拆分为 sql select.?
请注意,很少有名字可能没有标题或中间名首字母。我需要上面给出的输出。
使用regexp_substr (DB >=10g):
SELECT TRIM( REGEXP_SUBSTR(input_row, '[^,]+', 1, 1)) AS Last_NAME,
TRIM( REGEXP_SUBSTR( REGEXP_SUBSTR(input_row, '[^,]+', 1, 2), '[^ ]+', 1, 1)) AS First_Name,
TRIM( REGEXP_SUBSTR( REGEXP_SUBSTR(input_row, '[^,]+', 1, 2), '[^ ]+', 1, 2)) AS Middle_Initial,
TRIM( REGEXP_SUBSTR(input_row, '[^,]+', 1, 3)) AS Title
FROM source_table;
这是 Alexander 的答案,使用改进的正则表达式来处理 NULL 列表元素。哦,不要重复那个正则表达式,而是通过创建一个函数使其可重用,如下所述:REGEX to select nth value from a list, allowing for nulls,然后调用它。这样,所有代码都被封装并可重用,只有一个地方可以更改代码,如果您必须:
SQL> with tbl(input_row) as (
select 'Covey, Stephen J, Mr' from dual
union
select 'Clinton,,Ms' from dual
union
select 'Obama, Barack, Mr' from dual
)
SELECT TRIM( REGEXP_SUBSTR(input_row, '([^,]*)(,|$)', 1, 1, NULL, 1)) AS Last_NAME,
TRIM( REGEXP_SUBSTR( REGEXP_SUBSTR(input_row, '([^,]*)(,|$)', 1, 2, NULL, 1), '[^ ]+', 1, 1)) AS First_Name,
TRIM( REGEXP_SUBSTR( REGEXP_SUBSTR(input_row, '([^,]*)(,|$)', 1, 2, NULL, 1), '[^ ]+', 1, 2)) AS Middle_Initial,
TRIM( REGEXP_SUBSTR(input_row, '([^,]*)(,|$)', 1, 3, NULL, 1)) AS Title
FROM tbl;
LAST_NAME FIRST_NAME MIDDLE_INITIAL TITLE
-------------------- -------------------- -------------------- --------------------
Clinton Ms
Covey Stephen J Mr
Obama Barack Mr
SQL>
Oracle 11g R2 架构设置:
CREATE TABLE Names ( Name ) AS
SELECT 'Covey, Stephen J, Mr' FROM DUAL
UNION ALL SELECT 'Clinton, Hilary B,' FROM DUAL
UNION ALL SELECT 'Obama, Barack, Mr' FROM DUAL
查询 1:
SELECT REGEXP_SUBSTR( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', 1, 1, NULL, 1 ) AS Last_Name,
REGEXP_SUBSTR( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', 1, 1, NULL, 2 ) AS First_Name,
REGEXP_SUBSTR( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', 1, 1, NULL, 4 ) AS Middle_Initial,
REGEXP_SUBSTR( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', 1, 1, NULL, 5 ) AS Title
FROM Names
| LAST_NAME | FIRST_NAME | MIDDLE_INITIAL | TITLE |
|-----------|------------|----------------|--------|
| Covey | Stephen | J | Mr |
| Clinton | Hilary | B | (null) |
| Obama | Barack | (null) | Mr |
查询 2:
SELECT REGEXP_REPLACE( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', '' ) AS Last_Name,
REGEXP_REPLACE( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', '' ) AS First_Name,
REGEXP_REPLACE( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', '' ) AS Middle_Initial,
REGEXP_REPLACE( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', '' ) AS Title
FROM Names
| LAST_NAME | FIRST_NAME | MIDDLE_INITIAL | TITLE |
|-----------|------------|----------------|--------|
| Covey | Stephen | J | Mr |
| Clinton | Hilary | B | (null) |
| Obama | Barack | (null) | Mr |
查询 3:
WITH Split_Names AS (
SELECT REGEXP_SUBSTR( Name, '^[^,]+' ) AS Last_Name,
REGEXP_REPLACE( Name, '^.*?,\s*|\s*,.*?$' ) AS Given_Names,
REGEXP_SUBSTR( Name, '[^\s,]+$' ) AS Title
FROM Names
)
SELECT Last_Name,
REGEXP_REPLACE( Given_Names, '\s+\w$' ) AS First_Name,
TRIM( REGEXP_SUBSTR( Given_Names, '\s+\w$' ) ) AS Middle_Initial,
Title
FROM Split_Names
| LAST_NAME | FIRST_NAME | MIDDLE_INITIAL | TITLE |
|-----------|------------|----------------|--------|
| Covey | Stephen | J | Mr |
| Clinton | Hilary | B | (null) |
| Obama | Barack | (null) | Mr |
我需要拆分名称以插入数据库。下面给出了一些示例字符串。
Covey, Stephen J, Mr
Clinton, Hilary B,
Obama, Barack, Mr
我需要像下面这样拆分上面的字符串。
First_Name Middle_Initial Last_NAME Title
Stephen J Covey Mr
Hilary B Clinton
Barack Obama Mr
我可以使用 java 代码实现上述目标。是否可以将这些字符串直接拆分为 sql select.?
请注意,很少有名字可能没有标题或中间名首字母。我需要上面给出的输出。
使用regexp_substr (DB >=10g):
SELECT TRIM( REGEXP_SUBSTR(input_row, '[^,]+', 1, 1)) AS Last_NAME,
TRIM( REGEXP_SUBSTR( REGEXP_SUBSTR(input_row, '[^,]+', 1, 2), '[^ ]+', 1, 1)) AS First_Name,
TRIM( REGEXP_SUBSTR( REGEXP_SUBSTR(input_row, '[^,]+', 1, 2), '[^ ]+', 1, 2)) AS Middle_Initial,
TRIM( REGEXP_SUBSTR(input_row, '[^,]+', 1, 3)) AS Title
FROM source_table;
这是 Alexander 的答案,使用改进的正则表达式来处理 NULL 列表元素。哦,不要重复那个正则表达式,而是通过创建一个函数使其可重用,如下所述:REGEX to select nth value from a list, allowing for nulls,然后调用它。这样,所有代码都被封装并可重用,只有一个地方可以更改代码,如果您必须:
SQL> with tbl(input_row) as (
select 'Covey, Stephen J, Mr' from dual
union
select 'Clinton,,Ms' from dual
union
select 'Obama, Barack, Mr' from dual
)
SELECT TRIM( REGEXP_SUBSTR(input_row, '([^,]*)(,|$)', 1, 1, NULL, 1)) AS Last_NAME,
TRIM( REGEXP_SUBSTR( REGEXP_SUBSTR(input_row, '([^,]*)(,|$)', 1, 2, NULL, 1), '[^ ]+', 1, 1)) AS First_Name,
TRIM( REGEXP_SUBSTR( REGEXP_SUBSTR(input_row, '([^,]*)(,|$)', 1, 2, NULL, 1), '[^ ]+', 1, 2)) AS Middle_Initial,
TRIM( REGEXP_SUBSTR(input_row, '([^,]*)(,|$)', 1, 3, NULL, 1)) AS Title
FROM tbl;
LAST_NAME FIRST_NAME MIDDLE_INITIAL TITLE
-------------------- -------------------- -------------------- --------------------
Clinton Ms
Covey Stephen J Mr
Obama Barack Mr
SQL>
Oracle 11g R2 架构设置:
CREATE TABLE Names ( Name ) AS
SELECT 'Covey, Stephen J, Mr' FROM DUAL
UNION ALL SELECT 'Clinton, Hilary B,' FROM DUAL
UNION ALL SELECT 'Obama, Barack, Mr' FROM DUAL
查询 1:
SELECT REGEXP_SUBSTR( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', 1, 1, NULL, 1 ) AS Last_Name,
REGEXP_SUBSTR( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', 1, 1, NULL, 2 ) AS First_Name,
REGEXP_SUBSTR( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', 1, 1, NULL, 4 ) AS Middle_Initial,
REGEXP_SUBSTR( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', 1, 1, NULL, 5 ) AS Title
FROM Names
| LAST_NAME | FIRST_NAME | MIDDLE_INITIAL | TITLE |
|-----------|------------|----------------|--------|
| Covey | Stephen | J | Mr |
| Clinton | Hilary | B | (null) |
| Obama | Barack | (null) | Mr |
查询 2:
SELECT REGEXP_REPLACE( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', '' ) AS Last_Name,
REGEXP_REPLACE( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', '' ) AS First_Name,
REGEXP_REPLACE( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', '' ) AS Middle_Initial,
REGEXP_REPLACE( Name, '^(.*?),\s*(.*?)(\s+(\w))?,\s*(.*)$', '' ) AS Title
FROM Names
| LAST_NAME | FIRST_NAME | MIDDLE_INITIAL | TITLE |
|-----------|------------|----------------|--------|
| Covey | Stephen | J | Mr |
| Clinton | Hilary | B | (null) |
| Obama | Barack | (null) | Mr |
查询 3:
WITH Split_Names AS (
SELECT REGEXP_SUBSTR( Name, '^[^,]+' ) AS Last_Name,
REGEXP_REPLACE( Name, '^.*?,\s*|\s*,.*?$' ) AS Given_Names,
REGEXP_SUBSTR( Name, '[^\s,]+$' ) AS Title
FROM Names
)
SELECT Last_Name,
REGEXP_REPLACE( Given_Names, '\s+\w$' ) AS First_Name,
TRIM( REGEXP_SUBSTR( Given_Names, '\s+\w$' ) ) AS Middle_Initial,
Title
FROM Split_Names
| LAST_NAME | FIRST_NAME | MIDDLE_INITIAL | TITLE |
|-----------|------------|----------------|--------|
| Covey | Stephen | J | Mr |
| Clinton | Hilary | B | (null) |
| Obama | Barack | (null) | Mr |