我正在处理将一行拆分为多行的查询。 我的查询结果如下:
TEXTVALUE
1 Product1 P5 Product2 P19 Product3 P30 Product4 P11 Product5 P23
2 Product3 P30 Product7 P33
3 Product8 P53 Product5 P23 Product1 P5
我需要将其输出到:
PRODUCT AMOUNT
1 Product1 P5
2 Product1 P5
3 Product2 P19
4 Product3 P30
5 Product3 P30
6 Product4 P11
7 Product5 P23
8 Product5 P23
9 Product7 P33
10 Product8 P53
无论重复,我只需要在产品名称和金额之间进行基本分割。
有什么好的指示吗?
非常感谢!
答案 0 :(得分:2)
在这个简单的情况下拆分可以通过使用FTS世界破坏者来完成(如果产品名称包含破折号或其他字符,可以强制FTS解析器将其拆分为多个术语 - 创建UDF进行拆分,如前面的答案所示)。使用LEAD窗口函数(SQL Server 2012和需要上限)可以获得下一个值。这种方法只能进行一次表扫描。
CREATE TABLE #t (text nvarchar(100))
GO
INSERT INTO #t VALUES
('Product1 P5 Product2 P19 Product3 P30 Product4 P11 Product5 P23'),
('Product3 P30 Product7 P33'),
('Product8 P53 Product5 P23 Product1 P5');
WITH SplittedData AS
(
SELECT t.display_term AS PRODUCT,
ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS RowNumber,
LEAD(t.display_term, 1, NULL) OVER(ORDER BY (SELECT 1)) AS AMOUNT
FROM #t
CROSS APPLY sys.dm_fts_parser('"' + text + '"', 1033, NULL, 1) t
)
SELECT PRODUCT, AMOUNT
FROM SplittedData
WHERE RowNumber % 2 = 1
ORDER BY PRODUCT
DROP TABLE #t
GO
答案 1 :(得分:1)
我倾向于选择上面链接文章中列出的方法,称为Moden分割器。我不使用Aaron修改的版本,以便他的比较是一致的。我在这里发布原文。 http://www.sqlservercentral.com/articles/Tally+Table/72993/在此代码生效之前,您需要查看该页面并获取该拆分器的代码。
分割器优于大多数其他产品的一大优势是它返回单个项目的行号。你可以在这里很好地利用它来进行多级分割。
以下是使用计数表分割器的完整工作示例。
if OBJECT_ID('tempdb..#something')is not null
drop table #Something
create table #Something
(
SomeID int identity,
TextValue varchar(500)
)
insert #Something
select 'Product1 P5 Product2 P19 Product3 P30 Product4 P11 Product5 P23' union all
select 'Product3 P30 Product7 P33' union all
select 'Product8 P53 Product5 P23 Product1 P5';
with MySplitData as
(
select Item
, ItemNumber
, SomeID
from #Something s
cross apply dbo.DelimitedSplit8K(s.TextValue, ' ') x
)
select p.Product
, a.Amount
from
(
select Item as Product
, ItemNumber
, SomeID
from MySplitData
where ItemNumber % 2 = 1
) p
join
(
select Item as Amount
, ItemNumber
, SomeID
from MySplitData
where ItemNumber % 2 = 0
) a on a.ItemNumber = p.ItemNumber + 1
AND a.SomeID = p.SomeID
order by p.SomeID
, p.ItemNumber