2016-07-01 154 views
-4

我有數據輸入並希望在圖片中輸出。我如何寫它?如何將值拆分到另一列?

我可以在此SQL Server上運行,但我只得到寬度列(w_pacakaging),但我不知道寫擺脫列文本值長或高(DB名稱:[包裝列表文本])

我的代碼是

select [Packing list text],[Grade],[sales doc no], 
case when [Packing list text] like'%:%' then 
    cast(Ltrim(Rtrim(SUBSTRING([Packing list text], charindex(':', [Packing list text]) + 1, charindex('"', [Packing list text]) 

    - (charindex(':', [Packing list text]) + 1)))) as [nvarchar]) 
         END AS [W_packaging] 
from [TPC_CRSYS].[dbo].[TotalOrder_Export]            

從SQL Server

enter image description here

你怎麼能指點我寫SQL來獲取數據的結果長度和喚起注意從表[TotalOrder_Export]因爲它在每個記錄超過一個X

可能有人建議我

+0

標籤使用的數據庫管理系統。許多產品都有自己的非ANSI SQL字符串處理函數。 – jarlh

+1

請更具體。如果你寫出確切的問題,你會得到確切的答案 –

+0

我可以在SQL服務器上運行這個,但我只獲得寬度列,但我不知道要寫值的長度或從列的文本高 – monte

回答

1

使用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 

我希望這有助於