使用CTE和CHARINDEX簡單的方法:
;with
T AS (-- select the base table, adding an index for performances pourpose
SELECT *, ROW_NUMBER() OVER (ORDER BY [sales doc no],[Packing list text]) ROW_IDX
FROM [TPC_CRSYS].[dbo].[TotalOrder_Export]
),
W AS (-- SELECT ONLY ROWS WITH VALID DIMENSIONS AND CALC WIDTH POSITION
SELECT *, CHARINDEX('(WXLXH): ', [Packing list text])+9 W_POS
FROM T
WHERE CHARINDEX('(WXLXH): ', [Packing list text])>0
),
L AS (-- CALC LENGTH POSITION
SELECT *, CHARINDEX('"', [Packing list text], W_POS)+2 L_POS
FROM W
),
H AS (-- CALC HEIGHT POSITION
SELECT *, CHARINDEX('"', [Packing list text], L_POS)+2 H_POS
FROM L
),
X AS (-- CALC
SELECT *, CHARINDEX('"', [Packing list text], H_POS) END_POS
FROM H
)
SELECT T.[Packing list text], T.grade, T.[sales doc no]
, SUBSTRING(T.[Packing list text], W_POS, L_POS-2-W_POS) W
, SUBSTRING(T.[Packing list text], L_POS, H_POS-2-L_POS) L
, SUBSTRING(T.[Packing list text], H_POS, END_POS-H_POS) H
FROM T
LEFT JOIN X ON T.ROW_IDX = X.ROW_IDX
另外,您可以使用OUTER APPLY和拆分(FN_SPLIT)函數來獲得每行[裝箱清單文本]中的w/h/l,然後PIVOT他們ba CK一個單行:
;with
T AS (-- select the base table, adding an index for performances pourpose
SELECT *, ROW_NUMBER() OVER (ORDER BY [sales doc no], [Packing list text]) ROW_IDX
FROM [TPC_CRSYS].[dbo].[TotalOrder_Export]
),
W AS (-- SELECT ONLY ROWS WITH VALID DIMENSIONS AND CALC WIDTH POSITION
SELECT *, CHARINDEX('(WXLXH): ', [Packing list text])+9 W_POS
FROM T
WHERE CHARINDEX('(WXLXH): ', [Packing list text])>0
),
spl as (
select W.ROW_IDX, d.*
from w
outer apply (
select ID, SUBSTRING(data,2,100) VAL
from FN_SPLIT(SUBSTRING(w.[Packing list text], w_pos-1, 100),'"') s
where s.id<=3
) d
),
X AS (
SELECT *
FROM spl
PIVOT (MIN(VAL) FOR ID IN ([1],[2],[3])) P
)
SELECT T.[Packing list text], T.grade, T.[sales doc no], X.[1] W, X.[2] L, X.[3] H
FROM T
LEFT JOIN X ON T.ROW_IDX = X.ROW_IDX
這第二個版本是更快,如果你在你的[TotalOrder_Export表
的分割功能很多行,你會找到周圍很多版本,我做了這個:
CREATE FUNCTION [dbo].[FN_SPLIT]
(
@Line varchar(8000),
@SplitOn varchar(10) = ','
)
RETURNS @RtnValue table
(
Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED, -- VERY USEFUL TO MAKE JOINS AND TO CREATE THE UNIQUE INDEX ON SPLITTED STRINGS
Data varchar(800) NOT NULL,
UNIQUE (DATA, ID) -- THIS WILL MAKE REALLY FASTER THE QUERIES USING THIS FUNCTION
)
AS
BEGIN
IF @Line IS NULL RETURN
DECLARE @split_on_len INT = LEN(@SplitOn+'X')-1 -- TO CATCH TRAILING SPACES PROBLEM WITH LEN()
DECLARE @line_len INT = LEN(@line+'X')-1
DECLARE @start_at INT = 1
DECLARE @end_at INT
DECLARE @data_len INT
WHILE 1=1
BEGIN
IF @start_at > @line_len BREAK;
SET @end_at = CHARINDEX(@SplitOn, @Line, @start_at)
SET @data_len = CASE @end_at WHEN 0 THEN @line_len ELSE @[email protected]_at END
INSERT INTO @RtnValue (data) VALUES(SUBSTRING(@Line,@start_at,@data_len));
SET @start_at = @start_at + @data_len + @split_on_len
END
RETURN
END
我希望這有助於
標籤使用的數據庫管理系統。許多產品都有自己的非ANSI SQL字符串處理函數。 – jarlh
請更具體。如果你寫出確切的問題,你會得到確切的答案 –
我可以在SQL服務器上運行這個,但我只獲得寬度列,但我不知道要寫值的長度或從列的文本高 – monte