我有一个名称值对表,我在其中存储标签:
TAGID | NAME | VALUE
我有一张此标签适用的“事物”表
THINGID | TAGID
我需要一个查询来生成一个结果集,列/字段对于给定的 THINGID 都是可能的 TAG-NAMES(TAG 表中的 NAME 字段),并且值是对应的标签值。
THINGID | TAGNAME1 | TAGNAME2 | ... |etc.
我可以找到带有固定列的示例,但没有这样的。
我有一个名称值对表,我在其中存储标签:
TAGID | NAME | VALUE
我有一张此标签适用的“事物”表
THINGID | TAGID
我需要一个查询来生成一个结果集,列/字段对于给定的 THINGID 都是可能的 TAG-NAMES(TAG 表中的 NAME 字段),并且值是对应的标签值。
THINGID | TAGNAME1 | TAGNAME2 | ... |etc.
我可以找到带有固定列的示例,但没有这样的。
架构略有不同(thing_id、tag_name、tag_value)的类似内容 - 没有标签表:
CREATE PROCEDURE dbo.PivotData(@table VARCHAR(128), @basefield
VARCHAR(128), @namefield VARCHAR(128), @valuefield VARCHAR(128))
AS
DECLARE
@sql NVARCHAR(MAX)
SET @sql =
'DECLARE
@colName VARCHAR(128),
@sqlBegin NVARCHAR(MAX),
@sqlMiddle NVARCHAR(MAX),
@sqlEnd NVARCHAR(MAX),
@counter INT
SET @counter = 1
SET @sqlBegin = N''SELECT DISTINCT t0.'' + ''' + QUOTENAME(@basefield) + '''
SET @sqlMiddle = N'' FROM '' + ''' + QUOTENAME(@table) + ''' + '' AS t0 ''
DECLARE cols CURSOR FOR
SELECT DISTINCT TOP 100 PERCENT ' + QUOTENAME(@namefield) + '
FROM ' + QUOTENAME(@table) + '
WHERE ' + QUOTENAME(@basefield) + ' IS NOT NULL
ORDER BY ' + QUOTENAME(@namefield) + '
OPEN cols
FETCH NEXT FROM cols INTO @colName
WHILE @@FETCH_STATUS = 0 BEGIN
SET @sqlBegin = @sqlBegin + '', t'' + CAST(@counter AS VARCHAR) +
''.'' + ''' + QUOTENAME(@valuefield) + ''' + '' AS '' +
QUOTENAME(@colName) + ''''
SET @sqlMiddle = @sqlMiddle + '' LEFT OUTER JOIN '' + ''' +
QUOTENAME(@table) + ''' + '' AS t'' + CAST(@counter AS VARCHAR) +
'' ON t0.'' + ''' +
QUOTENAME(@basefield) + ''' + '' = t'' + CAST(@counter AS VARCHAR)
+ ''.'' + ''' +
QUOTENAME(@basefield) + ''' + '' AND t'' + CAST(@counter AS
VARCHAR) + ''.'' + ''' + QUOTENAME(@namefield) + ''' + ''='' +
QUOTENAME(@colName, '''''''') + ''''
SET @counter = @counter + 1
FETCH NEXT FROM cols INTO @colName
END
CLOSE cols
DEALLOCATE cols
SET @sqlEnd = '' WHERE t0.'' + ''' + QUOTENAME(@basefield) + ''' + ''
IS NOT NULL''
DECLARE @sql NVARCHAR(MAX)
SET @sql = @sqlBegin + @sqlMiddle + @sqlEnd
EXEC sp_executesql @sql'
EXEC sp_executesql @sql
RETURN 0
GO
CREATE TABLE test_data (
id int identity primary key,
person_id int,
person_data_field VARCHAR (128),
person_data_value VARCHAR (128)
)
GO
INSERT INTO dbo.test_data (person_id, person_data_field, person_data_value)
VALUES (1, 'Name', 'John')
INSERT INTO dbo.test_data (person_id, person_data_field, person_data_value)
VALUES (1, 'Surname', 'Smith')
INSERT INTO dbo.test_data (person_id, person_data_field, person_data_value)
VALUES (1, 'Email', 'John@Smith.com')
INSERT INTO dbo.test_data (person_id, person_data_field, person_data_value)
VALUES (2, 'Name', 'Sarah')
INSERT INTO dbo.test_data (person_id, person_data_field, person_data_value)
VALUES (2, 'Surname', 'Lee')
INSERT INTO dbo.test_data (person_id, person_data_field, person_data_value)
VALUES (2, 'Phone', '012345678')
GO
EXEC [dbo].[PivotData] @table='test_data',
@basefield='person_id', @namefield='person_data_field', @valuefield='person_data_value'
GO
我发现这工作得太慢了,并停止进一步调整它,但它有点符合您的要求。