在MS SQL Server版本"Microsoft SQL Server 2017 (RTM) - 14.0.1000.169 (X64)">
I am Read Only.
我有一个表T,有两列:a:nvarchar(255)和b:nvarchar(255)
我需要一个包含项目序列号的新列:
- 有时在a中,如果不是,则用1.2.3 这样的数字替换SN。
- 有时在b中,在描述字段中,如"…SN: A1234Z567890,…text. ">
我如何构建一个SELECT查询来提取在每种情况下工作的SN ?因为我没有创建函数的权限。
在PostgreSQL中,我会使用regexp_match(…),但我在SQL Server中找不到相同的。
在PostgresSQL服务器上,我会写这样一个请求:
选择合并(regexp_match (a,"([1-9A-Z]?)"),regexp_match (b。?SN :([1-9A-Z] * ?)")从T
如何使它在MS SQL Server上工作?
样本数据:
DECLARE @t TABLE (a nvarchar(255), b nvarchar(255))
insert into @t values
('1.2.344', 'blah blah SN: A123Z4567, blah blah')
, ('B2234567', 'irrelevant stuff not a serial 123')
, ('1.2.345', 'blah blah (SN: C32ZZ4567, blah) blah')
, ('1.2.345', 'blah blah (No Serial at all here blah) blah')
, ('', '');
期望作为额外列的输出:
serialnumber
==========
A123Z4567
B2234567
C32ZZ4567
NULL
NULL
我尝试使用与PostreSQL相同的请求:
SELECT Coalesce( regexp_match(A, '([1-9]*?)'), regexp_match(B, '.*?SN :([1-9]*?)') as serialnumber
FROM T
但是,由于我没有找到一个简单的方法来拥有regexp_match函数,我失去了,因为我没有设法继续。
= = =第二次尝试使用Allmhuran代码解决方案:
SELECT
a
, b
, patindex('%SN: %', b) as pi
, serialnumber = case
when a > '' and a not like '%[^0-9A-Z]%' then a
when b > '' then CONVERT(NVARCHAR(255), patindex('%SN: %', b))
-- when b > '' then substring(
-- b,
-- 4 + patindex('%SN: %', b),
-- charindex(
-- ',',
-- b,
-- 4 + patindex('%SN: %', b)
-- ) - 4 - patindex('%SN: %', b)
-- )
else null
end
FROM T
但是部分:
patindex('%SN: %', b)
返回0而不是预期的索引
提供一个保证100%正确的表达式是很困难的,但是…
作为查询:
-- create some sample data
create table t(a nvarchar(255), b nvarchar(255));
insert t values (null, 'blah blah SN: 12345, blah blah'), ('123', 'irrelevant stuff'), ('', '');
-- alter the table to add the expression as a computed column:
alter table t add serialNumber as
case
when a > '' and a not like '%[^0-9A-Z]%' then a
when patindex('%SN: %, %', b) > 0 then
substring(
b,
4 + patindex('%SN: %, %', b),
charindex(
',',
b,
4 + patindex('%SN: %, %', b)
) - 4 - patindex('%SN: %, %', b)
)
else null
end;