Spit列的下划线为多个列,并且还计算年龄

问题描述 投票:0回答:2

我有一个名为clients的表,并且我试图将包含下划线的值(其中的下划线是一列)拆分为多列,并且我还试图创建一列来计算年龄人。

这是表格的外观:

USERID  Vendors  (dobyr)  login  source
10bta   yes      1976     yes    google_hope
25cwd   yes      1986     yes    google_hln_1045
45tyj   no       1990     no     google_hln_4345
645io   no       1960     no     google    

目标是使外观看起来像这样:

USERID  Vendors  (dobyr)  login  Source1  Source2  Source3  Age
10bta   yes      1976     yes    google   hope     null      44
25cwd   yes      1986     yes    google   hln      1045      34
45tyj   no       1992     no     google   hln      4345      28
645io   no       1960     no     google   null     null      30   

不幸的是,使用我的代码时,google不在source1中。

这是我使用的代码:

 select *, datepart(year, CURRENT_TIMESTAMP)-dobyr AS Age,
 parsename(replace(source,'_','.'),1) AS source_1
,parsename(replace(source,'_','.'),2) AS source_2
,parsename(replace(source,'_','.'),3) AS source_3
,parsename(replace(source,'_','.'),4) AS source_4
 FROM clients

不幸的是,使用上面的代码,我得到了一个这样的表,其中所有google都不在column1中,但是得到了这样的内容:

 USERID  Vendors  (dobyr)  login  Source1  Source2  Source3  Age
 10bta   yes      1976     yes    google   hope     null     44
 25cwd   yes      1986     yes    hln      google   1045     34
 45tyj   no       1992     no     4345     hln      google   28
 645io   no       1960     no     null     null     google   30   
sql sql-server
2个回答
0
投票
下面,我使用charindex获取第一个下划线的位置。然后我再次使用它,得到第二个下划线。可能会知道charindex的第三个参数给出了起始位置。从那里开始,只是要确保如果位置为零,则返回null,然后校准子字符串以忽略结果中的下划线。

select userId, vendors, dobyr, login, source1 = iif(us1 = 0, null, substring(source, 1, us1 - 1)), source2 = iif(us1 = 0, null, substring(source, us1 + 1, len(source) - us2 - 1)), source3 = iif(us2 = 0, null, substring(source, us2 + 1, len(source) - us2 - 1)), age = datepart(year, getdate()) - dobyr from @clients c cross apply (select us1 = charindex('_', source)) ap1 cross apply (select us2 = charindex('_', source, us1 + 1)) ap2

而且我也继续尝试了bsv的xml方法,如Issac在对您的问题的评论中所链接。尽管如果您避免使用根级别的标签,它看起来会更简单:

select userId, vendors, dobyr, login, source1 = xml.value('src[1]', 'varchar(50)'), source2 = xml.value('src[2]', 'varchar(50)'), source3 = xml.value('src[3]', 'varchar(50)'), age = datepart(year, getdate()) - dobyr from @clients c cross apply (select xml = convert(xml, '<src>' + replace(source, '_', '</src><src>') + '</src>' )) ap;

很高兴我尝试了。我认为最终我更喜欢后者的语法,但是我认为性能会更差。

0
投票
您可以使用

SELECT UserId, Vendors, dobyr, login, source, MAX(CASE WHEN RN = 1 THEN Value END) Source1, MAX(CASE WHEN RN = 2 THEN Value END) Source2, MAX(CASE WHEN RN = 3 THEN Value END) Source3, MAX(YEAR(GETDATE()) - dobyr) Age FROM ( VALUES('10bta', 'yes', 1976, 'yes', 'google_hope'), ('25cwd', 'yes', 1986, 'yes', 'google_hln_1045'), ('45tyj', 'no', 1990, 'no', 'google_hln_4345'), ('645io', 'no', 1960, 'no', 'google') ) T(UserId, Vendors, dobyr, login, source) CROSS APPLY ( SELECT Value, ROW_NUMBER() OVER(ORDER BY (SELECT 1)) RN FROM STRING_SPLIT(Source, '_') )SS GROUP BY UserId, Vendors, dobyr, login, source;

© www.soinside.com 2019 - 2024. All rights reserved.