2017-08-24 23 views
0

我的公司在許多產品中使用通用日誌記錄數據庫。爲了防止需要大量的跨數據庫查詢,一些信息存儲在通用數據列內的分隔字段中以進行日誌記錄。Transact SQL將分割字符串轉換爲適當的列

我想要在數據上編寫查詢,但我不確定如何使用Pivot/Unpivot將數據存入適當的列?

下面是使用靜態數據爲我想要做的一般性示例,但不知道如何去做。我們很遺憾在SqlServer 2016中沒有內置的分割字符串函數,因此dbo.fnSplitString是我寫得很好的等價函數。

DECLARE @Columns TABLE (
    CustomerNumber VARCHAR(MAX) NOT NULL, 
    FirstName VARCHAR(MAX) NOT NULL, 
    LastName VARCHAR(MAX) NOT NULL); 

/* This isn't valid SQL ... unsure how to get this to work */ 
INSERT INTO @Columns PIVOT SELECT * FROM dbo.fnSplitString('STUFF1,STUFF2,STUFF3',','); 

SELECT * FROM @Columns; 

編輯:

這裏使用的例子,https://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx我能拿出一個解決方案。拆分字符串函數也需要輸出一個位置。這受到以下解決方案之一的啓發,只需將'OrdinalPosition'添加到該函數中即可。結果查詢起作用。

DECLARE @Columns TABLE (CustomerNumber VARCHAR(MAX) NOT NULL, FirstName VARCHAR(MAX) NOT NULL, LastName VARCHAR(MAX) NOT NULL); 

INSERT INTO @Columns select [0], [1], [2] from (SELECT position, splitdata FROM dbo.fnSplitString('STUFF1,STUFF4,STUFF3',',')) split pivot (MAX(splitdata) FOR position in ([0],[1],[2])) piv; 

SELECT * FROM @Columns; 
+0

什麼是你的fnSplitString函數?希望不是那個每個人都可以找到的帶有while循環的人。這裏的答案取決於你的分配器。 –

+0

我假設,每個字符串都應該放在表格的@Columns的每一列中。對? – Rex

+0

是的,這是@Rex的想法,它返回一個具有每個值的行的表。我需要將它轉換爲適合查詢的列。 – user2927848

回答

0

如果你的函數fnSplitString返回一個表,然後簡單地

INSERT INTO @Columns 
SELECT * FROM dbo.fnSplitString('STUFF1,STUFF2,STUFF3',',') 
PIVOT 
(
MAX(ParsedValue) 
FOR OrdinalPosition in ([0], [1], [2], [3]) 
) x 
+0

假設它是一個典型的分離器,它將以行的形式返回分隔值。 –

+0

是的,這是它將它們作爲行返回的問題。 – user2927848

+0

@ user2927848它現在使用序號位置 – domenicr

1

這是你在找什麼:
我只是用「項目」作爲列名。將其替換爲與從fnSplitString函數返回的名稱相對應的名稱。

DECLARE @Columns TABLE (CustomerNumber VARCHAR(MAX) NOT NULL, FirstName 
VARCHAR(MAX) NOT NULL, LastName VARCHAR(MAX) NOT NULL); 

INSERT INTO @Columns 
select STUFF1,STUFF2,STUFF3 from (SELECT item FROM 
dbo.fnSplitString('STUFF1,STUFF2,STUFF3',',')) d 
pivot (max(item) for item in (STUFF1,STUFF2,STUFF3)) piv; 

SELECT * FROM @Columns; 
+0

這看起來很接近,但是它的順序是由MAX命令的,我希望它們按照它們在字符串中的位置進行轉置。 – user2927848