仅选择SQL中某些子字符串后的数字

仅选择SQL中某些子字符串后的数字,sql,sql-server,Sql,Sql Server,我有多个行,其中包含一个具有不同值的字符串,其中一些行有数字,如下所示: XARELTO 20 MG 14 COM.(A)(P)85003(SC)(SF) 我需要得到字符串上的数字,但只需要在“(p)”后面的数字,这样我就可以得到: 85003 忽略编号85003之前(p)和之后的所有字符 例如,以下是一些行: | ProductName | +-----------------------------------------

我有多个行,其中包含一个具有不同值的字符串,其中一些行有数字,如下所示:

XARELTO 20 MG 14 COM.(A)(P)85003(SC)(SF)
我需要得到字符串上的数字,但只需要在“(p)”后面的数字,这样我就可以得到:

85003
忽略编号85003之前(p)和之后的所有字符

例如,以下是一些行:

| ProductName                                  |
+----------------------------------------------+
| VALCOTE 125 MG 30 CAP.(P)15188(SC)(SF)       |
+----------------------------------------------+
| ALPHAGAN SOL. OFT. 5 ML (A)(P)19347(SC)      |
+----------------------------------------------+
| LUMIGAN 0.03% OF.3ML(A)(P)67740(SC)(3%+)     |
+----------------------------------------------+
| BETALOC ZOK 50 MG 30 TBS (P)15390            |
+----------------------------------------------+
| CASODEX 50 MGS 28 TBS (E)(P)104334(SC)       |
+----------------------------------------------+
| SEROQUEL 100 MG 30 TBS(E)(A)(P)55800         |
+----------------------------------------------+
| SEROQUEL 200 MG 30 TBS (E)(A)(P)111600       |
+----------------------------------------------+
| SEROQUEL 25 MG 30 TBS (A)(P)13950            |
+----------------------------------------------+
这就是我在SELECT语句之后需要的:

| ProductPrice                                 |
+----------------------------------------------+
| 15188                                        |
+----------------------------------------------+
| 19347                                        |
+----------------------------------------------+
| 67740                                        |
+----------------------------------------------+
| 15390                                        |
+----------------------------------------------+
| 104334                                       |
+----------------------------------------------+
| 55800                                        |
+----------------------------------------------+
| 111600                                       |
+----------------------------------------------+
| 13950                                        |
+----------------------------------------------+

在示例数据中,数字都有五位数字。这表明:

select left(stuff(str, 1, patindex('%(P)[0-9][0-9][0-9][0-9]%', str) + 2, ''), 5)
from (values ('XARELTO 20 MG 14 COM.(A)(P)85003(SC)(SF)')) v(str);
SQL Server不擅长处理字符串。这可以修改为处理可变位数,但表达式要复杂一些

编辑:

以下是适用于任意长度的版本:

select left(v.str + ' ', patindex('%[^0-9]%', v.str + ' ') - 1)
from (values ('XARELTO 20 MG 14 COM.(A)(P)85003(SC)(SF)'),
             ('SEROQUEL 200 MG 30 TBS (E)(A)(P)111600')
     ) x(str) cross apply
     (values (stuff(x.str, 1, patindex('%(P)[0-9][0-9][0-9][0-9]%', x.str) + 2, ''))) v(str);

这并不漂亮,但很管用。但是,这并不假设所有值都有5个字符:

WITH VTE AS(
    SELECT *
    FROM (VALUES('VALCOTE 125 MG 30 CAP.(P)15188(SC)(SF)  '),
                ('ALPHAGAN SOL. OFT. 5 ML (A)(P)19347(SC) '),
                ('LUMIGAN 0.03% OF.3ML(A)(P)67740(SC)(3%+)'),
                ('BETALOC ZOK 50 MG 30 TBS (P)15390       '),
                ('CASODEX 50 MGS 28 TBS (E)(P)104334(SC)  '),
                ('SEROQUEL 100 MG 30 TBS(E)(A)(P)55800    '),
                ('SEROQUEL 200 MG 30 TBS (E)(A)(P)111600  '),
                ('SEROQUEL 25 MG 30 TBS (A)(P)13950       '))V(ProductName))
SELECT V.ProductName,
       LEFT(S.R,ISNULL(NULLIF(CHARINDEX('(',S.R),0)-1,LEN(S.R))) AS ProductPrice
FROM VTE V
     CROSS APPLY (VALUES(PATINDEX('%(P)%',V.ProductName)))PI(I)
     CROSS APPLY (VALUES(STUFF(V.ProductName,1,PI.I+2,'')))S(R);

理想情况下,您需要修复您的设计。您不应该在一列中存储包含多个不同信息位的数据。它们都应该存储在一个目标列和/或行中。检查SQL Server,试一试,然后在遇到问题时发布您的尝试。学习正确的数据库设计应该是您应该做的第一步。“在示例数据中,数字都有五位数字。”它们没有,请看第5和第7个示例;它们有6个数字。@Larnu。我更喜欢我的视力;)