Я полностью согласен с сделанными комментариями, и это далеко не идеальный способ хранения данных.Ваша таблица Form
должна быть нормализована, и на самом деле вы должны использовать свой уровень представления для этого.Я написал ниже, используя STRING_SPLIT
, однако вы также можете использовать DelimitedSplit8k_LEAD
для достижения этой цели.(Исправление вам понадобится, поскольку вы используете SQL Server 2012.)
Это не материал начального уровня, поэтому, пожалуйста, спросите, если не понимаете:
--Create the table with all the items
CREATE TABLE dbo.Item (ItemID int IDENTITY (1,1),
ItemName varchar(2));
INSERT INTO dbo.Item(ItemName)
VALUES('a'),
('b'),
('c'),
('d'),
('e'),
('f'),
('g'),
('h'),
('i'),
('j'),
('k'),
('l'),
('m'),
('n'),
('o'),
('p'),
('q');
GO
--And now your sample data
CREATE TABLE dbo.Form (Pk int IDENTITY (1,1),
Items varchar(100)); --Really you shouldn't be storing delimited data
INSERT INTO dbo.Form (Items)
VALUES ('a,b,c'),
('d,e,f'),
('g,h,i'),
('j,k,l');
GO
--Declare the SQL variable to store the dynamic SQL
DECLARE @SQL nvarchar(MAX);
--Build the SQL. Use FOR XML PATH to create the delimited list of columns,
--STRING_SPLIT in the dynamic SQL to split the data
--and a cross tab to pivot the data
--YUCK (sorry)
SET @SQL = N'SELECT F.Pk,' + NCHAR(13) + NCHAR(10) +
STUFF((SELECT N',' + NCHAR(13) + NCHAR(10) +
N' CASE WHEN COUNT(CASE WHEN SS.[value] = ' + QUOTENAME(I.ItemName,'''') + N'THEN 1 END) = 0 THEN 0 ELSE 1 END AS ' + QUOTENAME(I.ItemName)
FROM dbo.Item I
ORDER BY I.ItemName ASC
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,3,N'') + NCHAR(13) + NCHAR(10) +
N'FROM dbo.Form F' + NCHAR(13) + NCHAR(10) +
N' CROSS APPLY STRING_SPLIT(F.Items,'','') SS' + NCHAR(13) + NCHAR(10) +
N'GROUP BY Pk;';
PRINT @SQL; --Your best friend for debugging
EXEC sp_executesql @SQL;
GO
DROP TABLE dbo.Form;
DROP TABLE dbo.Item;
**
1011 дб <> скрипка