SQL 查询:如何从一列返回一列子字符串?

时间:2021-04-15 18:29:35

标签: sql oracle csv

我已经尝试过类似问题的答案,但它们对我不起作用。我有一列文本,其中包含我感兴趣的子字符串。我想用这些子字符串创建一个新列。

person_table:

<头>
person_details
姓名:John Doe,DoB:1973-04-15,地址:123 Main St
姓名:Jane Doe,DoB:1982-03-24,地址:123 Main St,职业:开发商
姓名:James Smith,DoB:1990-07-07

期望:

<头>
person_details DoB
姓名:John Doe,DoB:1973-04-15,地址:123 Main St 1973-04-15
姓名:Jane Doe,DoB:1982-03-24,地址:123 Main St,职业:开发商 1982-03-24
姓名:James Smith,DoB:1990-07-07 1990-07-07

这是一个简化的例子。我不知道中间名将从字符串中的哪个位置开始,所以我需要搜索一个模式。

我尝试了以下方法:

select person_details, regexp_extract(person_details, "[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])") as DoB
from person_table;

select person_details, extract(person_details, "[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])") as DoB
from person_table;

select person_details, regexp_substr(person_details, "[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])") as DoB
from person_table;

但这些都给我错误。

我怎样才能获得这个新专栏?

3 个答案:

答案 0 :(得分:1)

由于各种原因,这不是存储数据的好方法。每次在运行时解析数据都会很慢,索引这将非常非常困难,等等。至少如果您将复合数据存储为 JSON 或 XML,根据 Oracle 版本,有一些内置的 -在函数中解析和索引 JSON 和 XML,因此您并非完全没有工具。但即便如此,您几乎肯定希望在加载数据时解析出常用字段。

我会使用 simple instr and substr。假设您可以只查找字符串“DoB:”并且日期的长度始终为 10 个字符,那么您可以执行以下操作。

with p as (
  select 'Name: John Doe, DoB: 1973-04-15, Address: 123 Main St' person_details from dual union all
  select 'Name: Jane Doe, DoB: 1982-03-24, Address: 123 Main St, Occupation: Developer' from dual union all
  select 'Name: James Smith, DoB: 1990-07-07' from dual
)
select substr( person_details, instr( person_details, 'DoB: ')+5, 10 ) dob
  from p

如果日期不总是 10 个字符,您可以在字符串中查找“DoB:”之后的第一个逗号并使用它来计算长度。

答案 1 :(得分:0)

你可以试试这个。可能不是最有效的方法,但它可以完成工作。

declare @person_table TABLE(personInfo nvarchar(200))

插入@person_table (personInfo) values('Name: John Doe, DoB: 1973-04-15, Address: 123 Main St') 插入@person_table (personInfo) 值('姓名:Jane Doe,DoB:1982-03-24,地址:123 Main St,职业:开发人员') 插入@person_table (personInfo) values('Name: James Smith, DoB: 1990-07-07');

选择个人信息, 案件 当 personInfo 像 '%DoB%[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]%' /* 请注意CHARINDEX中的+5是'DoB:'的长度,10是DoB的字符串长度*/ THEN substring(personInfo,CHARINDEX('DoB: ',personInfo)+5,10) else 'No DoB' end DoB 来自@person_table

答案 2 :(得分:0)

只想重新格式化代码

declare @person_table TABLE(personInfo nvarchar(200))

insert into @person_table (personInfo) values('Name: John Doe, DoB: 1973-04-15, Address: 123 Main St')
insert into @person_table (personInfo) values('Name: Jane Doe, DoB: 1982-03-24, Address: 123 Main St, Occupation: Developer')
insert into @person_table (personInfo) values('Name: James Smith, DoB: 1990-07-07');

select personinfo, 
    case
        WHEN personInfo like '%DoB%[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]%' 
            /* Please note that +5 in the CHARINDEX is the length of 'DoB: ' and 10 is the string length of the DoB*/
            THEN substring(personInfo,CHARINDEX('DoB: ',personInfo)+5,10) else 'No DoB' end DoB 
from @person_table
相关问题