2016-08-05 155 views
0

我繼承了一個表(誰沒有,對吧?),有看起來像這樣的數據:治療多發性分隔符分隔字段重複行

Item   |    Properties  |  Quantity 
-------------------------------------------------------------------- 
Shirt   | button-down,polo,sleeveless |   4,5,8 

在短期內,我想創建一個視圖,但最終我想將數據導出表中的一個新版本時,時間允許和有它更像是:

Item   |    Properties  |  Quantity 
-------------------------------------------------------------------- 
Shirt   |   button-down  |   4 
Shirt   |    polo   |   5 
Shirt   |    sleeveless  |   8 

從本質上講,採取多列組(我想象還會有其他的表那裏有更多的列比兩個具有這種行爲)已知是分隔符和bre將它們分爲不同的行?收集到的其他不同於此的行將在它們之間共享,如本例中的Item。這些類型之間的逗號數是統一的。

編輯:我以前在答案中給出的函數How to convert comma separated NVARCHAR to table records in SQL Server 2005?,這是目前我有:

select distinct data.item, tmptbl.[String] from 
    data cross apply [ufn_CSVToTable](data.properties, ',') tmptbl ... 

這工作在單柱背景,但應用該功能,第二列(數量在這種情況下)徹底會產生所有可能的性質和數量的組合,對吧?事實上,是的,當我嘗試時,確實導致了這種情況。看起來我需要一個光標或類似的符號來有效地分解成單獨的屬性行[i] |數量[我],將嘗試和構建。這或者可能只是選擇數據並在應用程序端分割它。

+1

類教學SQL剛剛結束。我在最後幾分鐘看到了關於sql/tsql的多個未定義的問題,其中沒有一個顯示他們自己嘗試解決的代碼。請包括**你自己嘗試過的地方,遇到問題的地方以及確切而確切的問題**,否則你的問題不能回答。 –

+0

好的,謝謝。將更新爲包含(儘管它只允許以這種方式打破單個列)。 – Robert

+0

您是使用SQL Server 2005還是剛剛提到它?使用適當的軟件(MySQL,Oracle,DB2,...)和版本(例如, '的SQL服務器2014'。語法和功能的差異往往會影響答案。 – HABO

回答

2

使用從here分割字符串之一..

如果你確定屬性將始終有相同數量算作數量(我的意思是在性能3個價值觀和數量3個值),那麼您可以更換與內一個低於加入..

;With cte 
as 
(select t.item ,a1.item as 'Properties',row_number() over (order by (select null)) as rownum1 
from #test t 
cross apply 
[dbo].[SplitStrings_Numbers](proper,',') a1 
) 
,cte1 as 
(
select a2.item as quantity,row_number() over (order by (select null)) as rownum2 
from #test t 
cross apply 
[dbo].[SplitStrings_Numbers](quantity,',') a2 
) 
Select c.ite,c.Properties,c1.quantity 
from cte c 
full join 
cte1 c1 
on c.rownum1=c1.rownum2 

輸出:

item Properties quantity 
Shirt button-down 4 
Shirt polo   5 
Shirt sleeveless  8 
+0

啊,這是一個非常新穎的做法:單獨拆分,加入行號。會給那一槍。 – Robert

0
CREATE FUNCTION [dbo].[ReturnTableOfVarchars] 
    (@IDList varchar(8000)) 
    -- allow up to 256 varchar 
    RETURNS @IDTable table (RecordID varchar(256) NOT NULL) 
AS 
    BEGIN 
    DECLARE @IDListPosition int, 
     @ArrValue varchar(8000) 
    SET @IDList = COALESCE(@IDList,'') 
    IF @IDList<>'' 
     BEGIN 
     -- add a comma to end of list 
     SELECT @IDList = @IDList+',' 
     -- Loop through the comma delimited string list 
     WHILE PATINDEX('%,%',@IDList)<>0 
     BEGIN 
      -- find the position of the first comma in the list 
      SELECT @IDListPosition = PATINDEX('%,%',@IDList) 
      -- extract the string 
      SELECT @ArrValue = LEFT(@IDList, @IDListPosition - 1) 
      INSERT @IDTable (RecordID) VALUES(@ArrValue) 
      -- remove processed string 
      SELECT @IDList = STUFF(@IDList,1,@IDListPosition ,'') 
     END 
     END 
    RETURN 
    END 

使用:

declare @itemvalues varchar(100) ,@itemcount varchar(100) 
set @itemvalues='button-down,polo,sleeveless' 
SET @itemcount =' 4,5,8' 

select * from dbo.ReturnTableOfVarchars(@itemvalues) 
select * from dbo.ReturnTableOfVarchars(@itemcount) 

以上函數從字符串拆分值,你可以從選擇或更新根據您的過程中插入的值。

+0

這似乎是以類似於CSVToTable函數的方式處理的。有沒有辦法加入這些按鈕| 4,polo | 5等? – Robert

1

隨着他分離器和交叉的LP適用

Declare @YourTable table (item varchar(50),Properties varchar(50),Quantities varchar(50)) 
Insert into @YourTable values 
('Shirt','button-down,polo,sleeveless','4,5,8') 


Select A.item 
     ,B.Properties 
     ,B.Quantities 
From @YourTable A 
Cross Apply (Select Properties=A.Key_Value 
        ,Quantities=B.Key_Value 
       From (Select * from [dbo].[udf-Str-Parse](A.Properties,',')) A 
       Left Join (Select * from [dbo].[udf-Str-Parse](A.Quantities,',')) B on A.Key_PS=B.Key_PS 
) B 

返回

item Properties Quantities 
Shirt button-down 4 
Shirt polo   5 
Shirt sleeveless 8 

的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',' ') 
--  Select * from [dbo].[udf-Str-Parse]('id26,id46|id658,id967','|') 
--  Select * from [dbo].[udf-Str-Parse]('hello world. It. is. . raining.today','.') 

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