2017-08-24 16 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