Sql server 从带分隔符的字符串中提取数字,格式不同
我正在尝试从运行SQL Server 2014的ERP系统中连接两个表,Sql server 从带分隔符的字符串中提取数字,格式不同,sql-server,join,Sql Server,Join,我正在尝试从运行SQL Server 2014的ERP系统中连接两个表,OrderLines和Production。其工作方式是,如果将产品添加到订单中,并且该产品没有库存,则会自动生成用于生产的“生产分录”(基本上是物料清单) OrderLines表中的GeneratedEntries字段捕获该数据,记录为该订单行生成的生产条目号。该字段通常采用以下格式:它以PD~开头,然后是条目号,随后的条目号由另一个波浪号~分隔。因此,对于导致生成2个条目号的订单行,此字段的标准值可能如下所示: PD~1
OrderLines
和Production
。其工作方式是,如果将产品添加到订单中,并且该产品没有库存,则会自动生成用于生产的“生产分录”(基本上是物料清单)
OrderLines
表中的GeneratedEntries
字段捕获该数据,记录为该订单行生成的生产条目号。该字段通常采用以下格式:它以PD~
开头,然后是条目号,随后的条目号由另一个波浪号~
分隔。因此,对于导致生成2个条目号的订单行,此字段的标准值可能如下所示:
PD~12345~67891
问题是,该字段的格式有时不一致,有时会有尾随的波浪号,有时字符串中间会重复PD~
,还有其他多余的垃圾字符,等等
我不知道如何从GeneratedEntries
中提取条目号来连接两个表,这种方式适用于所有格式设置。有没有办法做到这一点
下面有相关列的示例表(OrderNumber和Product实际上并不相关,只是用于上下文…)
实际上,任何解析/拆分函数都可以。这里是一个内联方法 唯一的技巧是用~替换任何空格,用try_convert()替换过滤器 示例
Declare @YourTable Table ([OrderNumber] varchar(50),[Product] varchar(50),[GeneratedEntries] varchar(50))
Insert Into @YourTable Values
(1,'A','PD~10005')
,(1,'B','PD~10006~')
,(1,'C','PD~10007~10008~10009')
,(2,'R','PD~10010~~10011')
,(2,'L','~PD~10012~~')
,(2,'Z','PD~10013 PD~10014')
Select A.OrderNumber
,A.Product
,B.*
From @YourTable A
Cross Apply (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace(replace([GeneratedEntries],' ','~'),'~','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
) B
Where try_convert(int,B.RetVal) is not null
OrderLines表上的主键是什么?@MaxSzczurek主键是
OrderNumber
,它通常连接到一个单独的Orders
表,该表包含所有主订单标题信息。我认为这与这个问题无关。OrderNumber是orders表的主键,而不是OrderLines表。您需要建立每行的唯一性。OrderLines表的主键是什么?我猜它是OrderNumber和其他字段的组合,比如一行#。这与你的问题绝对相关。是的,你是对的,我的错。OrderLines的主键是OrderNumber和LineItem(如您所猜测的,第#行),非常感谢,这看起来非常有效。我不知道这一切意味着什么,但我会尝试将您的查询分开。此外,正如@MaxSzczurek正确指出的那样,我在问题中忽略了提到,OrderLines
的主键是OrderNumber
和LineItem
。因此,我只需将LineItem
添加到您的查询中,并在这两个字段上进行联接。@wysiwyg很高兴这有帮助,我们将完成联接。
Declare @YourTable Table ([OrderNumber] varchar(50),[Product] varchar(50),[GeneratedEntries] varchar(50))
Insert Into @YourTable Values
(1,'A','PD~10005')
,(1,'B','PD~10006~')
,(1,'C','PD~10007~10008~10009')
,(2,'R','PD~10010~~10011')
,(2,'L','~PD~10012~~')
,(2,'Z','PD~10013 PD~10014')
Select A.OrderNumber
,A.Product
,B.*
From @YourTable A
Cross Apply (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace(replace([GeneratedEntries],' ','~'),'~','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
) B
Where try_convert(int,B.RetVal) is not null
OrderNumber Product RetSeq RetVal
1 A 2 10005
1 B 2 10006
1 C 2 10007
1 C 3 10008
1 C 4 10009
2 R 2 10010
2 R 4 10011
2 L 3 10012
2 Z 2 10013
2 Z 4 10014