选择字符串的特定部分

时间:2016-08-09 16:00:12

标签: sql sql-server sql-server-2008 tsql sql-server-2008-r2

我试图提取字符串的特定部分,这可能是字符串中的任何位置。

07-16 ACADIA/07-10 OUTLOOK/08-16 ENCLAVE/09-16 TRAVERSE FLOORLINER

例如,这里有多个年份范围的描述。我需要提取07-1607-1008-1609-16。我有提取07-16的代码,但我现在开始迷失在代码中,试图弄清楚如何 提取它们。我还需要让模型与我们数据库中的模型进行比较,但是很多描述中的模型都有很小的不一致性

例如:Ford F-150, F-250... Ford F 150, F 250.. Ford F150, F250.. etc.

F-150将是存储在数据库中的正确值以进行比较。

这是一个用于创建样本数据的临时表脚本

CREATE TABLE #mytable(
DESCRIPTION     VARCHAR(101) 
);
INSERT INTO #mytable VALUES ('07-16 ACADIA/07-10 OUTLOOK/08-16 ENCLAVE/09-16 TRAVERSE REAR FLOORLINER GREY'  );
INSERT INTO #mytable VALUES ('08-16 F250/F350/F350/F-450 TECHSHADE NA'      );
INSERT INTO #mytable VALUES ('07-16 SILVERADO/SIERRA 1500/15-16 SILVERADO/SIERRA 2500/3500 5FT 9.25IN TECHLINER BLACK ');
INSERT INTO #mytable VALUES ('97-94 BLAZER FS/95-99 TAHOE 2DR/92-97 YUKON 2DR CARGO LINERS TAN');
INSERT INTO #mytable VALUES ('66-72 MERCEDES-BENZ SE/SEL 4.5/108/109  66-73 250S/250SE/280S/300SEB/300SEL TECHSHADE '        );
INSERT INTO #mytable VALUES ('66-70 FAIRLANE/TORINO  68-71 RANCHERO TECHSHADE   '      );
INSERT INTO #mytable VALUES ('07-13 MINI COOPER/12-13 COUPE/ROADSTER/02-06 CLUBMAN FRONT RUBBER MATS TAN' );
INSERT INTO #mytable VALUES ('60-63 PORSCHE 356B  64-65 356C TECHSHADE ');

这是我到目前为止用于拉动第一年范围的代码

SELECT Left(
            SubString(DESCRIPTION, PatIndex('%[0-9.-]%', DESCRIPTION), 5),
            PatIndex('%[^0-9.-]%', SubString(DESCRIPTION, PatIndex('%[0-9.-]%', DESCRIPTION), 5) + 'X')-1)
FROM #myTable

我正在寻找与提供的查询一样可以证明的类似结果。我只需要隔离它们,以便我可以将这些年份转换为日期时间格式,以便进一步比较。

+-------+-------+-------+-------+
| rng1  | rng2  | rng3  | rng4  |
+-------+-------+-------+-------+
| 07-16 | 07-10 | 08-16 | 09-16 |
| 08-16 |       |       |       |
| 07-16 | 15-16 |       |       |
| 97-94 | 95-99 | 92-97 |       |
| 66-72 | 66-73 |       |       |
| 66-70 | 68-71 |       |       |
| 07-13 | 12-13 | 02-06 |       |
| 60-63 | 34-65 |       |       |
+-------+-------+-------+-------+

大多数年份范围从一开始就开始,没有办法确定第二个范围的开始位置,并非所有这些范围都用这样的反斜杠分割07-16 ACADIA/07-10 OUTLOOK

描述中有多少不同的年份范围也是不确定的,而不知道每个特定描述中有多少。这些是我正在使用的实际样本。

最重要的问题是,我要求的是什么,以及如何找到解决方案。

3 个答案:

答案 0 :(得分:0)

听起来你需要一个字符串分割器。这里有几个很棒的选择。 Python Docs使用StringSplit_XML你可以做这样的事情。

ZipEntry

答案 1 :(得分:0)

DECLARE @TABLE AS TABLE (ID int,DESCRIPTION VARCHAR(101))
Insert Into @Table values
(1,'07-16 ACADIA/07-10 OUTLOOK/08-16 ENCLAVE/09-16 TRAVERSE FLOORLINER')

SELECT A.ID
      ,A.DESCRIPTION
      ,B.Key_PS
      ,B.Key_Value
      ,SomeField1 = substring(B.Key_Value,1,5)
      ,SomeField2 = substring(B.Key_Value,6,200)
FROM @TABLE A
Cross Apply (Select * from [dbo].[udf-Str-Parse](A.DESCRIPTION,'/')) B

返回

ID  DESCRIPTION                                                         Key_PS    Key_Value     SomeField1  SomeField2
1   07-16 ACADIA/07-10 OUTLOOK/08-16 ENCLAVE/09-16 TRAVERSE FLOORLINER  1         07-16 ACADIA  07-16       ACADIA
1   07-16 ACADIA/07-10 OUTLOOK/08-16 ENCLAVE/09-16 TRAVERSE FLOORLINER  2         07-10 OUTLOOK 07-10       OUTLOOK
1   07-16 ACADIA/07-10 OUTLOOK/08-16 ENCLAVE/09-16 TRAVERSE FLOORLINER  3         08-16 ENCLAVE 08-16       ENCLAVE
1   07-16 ACADIA/07-10 OUTLOOK/08-16 ENCLAVE/09-16 TRAVERSE FLOORLINER  4         09-16 TRAVERS 09-16       TRAVERSE FLOORLINER

UDF(如果需要)

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimeter varchar(10))
--Usage: Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--       Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')

Returns @ReturnTable Table (Key_PS int IDENTITY(1,1), Key_Value varchar(max))
As
Begin
   Declare @XML xml;Set @XML = Cast('<x>' + Replace(@String,@Delimeter,'</x><x>')+'</x>' as XML)
   Insert Into @ReturnTable Select Key_Value = ltrim(rtrim(String.value('.', 'varchar(max)'))) FROM @XML.nodes('x') as T(String)
   Return 
End

答案 2 :(得分:-1)

我认为你所寻找的是一个正则表达式。没有正则表达式就可以实现相同的功能,但正则表达式是紧凑的解析函数。

https://regex101.com/

此站点可用于构建和测试正则表达式,我认为另一种方法是构建可重用的函数,如上例所示。