如何解决T-SQL-列字符串
很抱歉,我没有找到答案的问题。
我在下面的专栏中有以下叙述
叙事
- 此预算为68000英镑
- 产品C的价格为300000英镑
- 产品B的价格为-6650欧元
我设法用case语句创建了一个货币列,现在我试图创建一个仅包含数值的列,并删除除数值之外的所有文本。
我想摆脱拥有
Narrative
---------------------------------
The budget for this is 68000 GBP
Product C will cost GBP 300000
Product B will cost -6650 EUR
到
Values Currency
---------------------
68000 GBP
300000 GBP
(650) EUR
我只是想知道是否有使用T-SQL进行此操作的快速方法。我可以使用的叙事栏中没有定界符,但数值始终是字符串中的最后一个文本。
非常感谢
对不起,我还没有做到这一点,可能是新手,我无法解释,但这是我的代码
〜SELECT SYSAccountingPeriodID,GoodsValueInBaseCurrency,TransactionDate,引用,叙述,用户名, 叙事类似'%USD%'则为'USD'的情况叙事类似'%EURP'则为'GBP'则叙事类似'%EUR%'的则为'EUR'否则为'EUR' 来自dbo.NLPostedNominalTran〜
这是输出
解决方法
假设,select col,(select dateadd(month,1,min(col))
from t t2
where t2.col > t.col
)
from t;
中的最后两个“单词”是价格和货币,您可以执行以下操作。由于数据不一致(Narrative
和Price Currency
都出现),并且Currency Price
字符不是价格值的一部分,因此这比应该的情况更加混乱。>
-
请注意,我也将值转换为SELECT TRY_CONVERT(decimal(10,2),CASE WHEN LS.FirstWord LIKE '%[^0-9]%' THEN LS.SecondWord ELSE LS.FirstWord END) * IIF(LR.Minus = '-',-1,1) AS Price,CASE WHEN LS.FirstWord LIKE '%[^0-9]%' THEN LS.FirstWord ELSE LS.SecondWord END AS Currency
FROM (VALUES('The budget for this is 68000 GBP'),('Product C will cost GBP 300000'),('Product B will cost - 6650 EUR'))V(Narrative)
CROSS APPLY (VALUES(CHARINDEX(' ',REVERSE(V.Narrative))))CI1(I)
CROSS APPLY (VALUES(CHARINDEX(' ',REVERSE(V.Narrative),CI1.I+1)))CI2(I)
CROSS APPLY (VALUES(RIGHT(V.Narrative,CI2.I-1)))R(Price)
CROSS APPLY (VALUES(LEFT(R.Price,CHARINDEX(' ',R.Price)-1),STUFF(R.Price,R.Price),'')))LS(FirstWord,SecondWord)
CROSS APPLY (VALUES(LEFT(RIGHT(V.Narrative,CI2.I+1),1)))LR(Minus)
中的decimal
。如果只能使用整数值,则可以在其中使用SELECT
。
在您的实际预期结果中,您有int
。我假设 '(650)'
是一个印刷错误,因为样本数据具有650
。至于用括号(6650
)表示的值是负数,则应在表示层进行;因此在数据引擎中它将显示为()
(假设为-6650.00
)。
如果您使用的是SQL Server 2016或更高版本,则可以使用string_split函数。将其与公用表表达式(CTE),一些apply
和case
语句结合使用,您可以构建以下解决方案。
您的样本数据在减号和值之间有一个空格。如果在整个数据集中情况并非总是如此,则该方法可能需要进行一些调整,但可以保留一般的解决方案路径。
- 基于空格将字符串拆分为值
- 过滤掉数值(包括减号)和货币
- 从数值开始并附加货币,使用
case
设置负值格式
样本数据
declare @data table
(
narative nvarchar(50)
);
insert into @data (narative) values
('The budget for this is 68000 GBP'),('Product B will cost - 650 EUR');
解决方案
with cte as
(
select d.narative,s.value,case when s.value = '-' then 1 else 0 end as 'IsNeg',isnumeric(s.value) as 'IsNum'
--case when try_convert(decimal(10,s.value) is not null then 1 else 0 end as 'IsNum2'
from @data d
cross apply string_split(d.narative,' ') s
where isnumeric(s.value) = 1
or s.value in ('EUR','GBP')
)
select c1.narative,case when c4.IsNeg = 1 then '(' else '' end
+ c1.value
+ case when c4.IsNeg = 1 then ') ' else ' ' end
+ c3.value as 'money'
from cte c1
cross apply ( select c2.value
from cte c2
where c2.narative = c1.narative
and c2.IsNum = 0 ) c3
outer apply ( select c2.IsNeg
from cte c2
where c2.narative = c1.narative
and c2.IsNeg = 1 ) c4
where c1.IsNum = 1
and c1.IsNeg = 0;
结果
-- cte
narative value IsNeg IsNum
----------------------------------- --------- ----------- -----------
The budget for this is 68000 GBP 68000 0 1
The budget for this is 68000 GBP GBP 0 0
Product C will cost GBP 300000 GBP 0 0
Product C will cost GBP 300000 300000 0 1
Product B will cost - 650 EUR - 1 1
Product B will cost - 650 EUR 650 0 1
Product B will cost - 650 EUR EUR 0 0
-- final
narative money
----------------------------------- -------------
The budget for this is 68000 GBP 68000 GBP
Product C will cost GBP 300000 300000 GBP
Product B will cost - 650 EUR (650) EUR
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。