我不确定这是否会被称为旋转。
我的SQL 2005表 [CustromerRoles] 中的数据是这样的:
CustId RoleId
2 4
2 3
3 4
4 1
4 2
[角色] 表:
RoleId Role
1 Admin
2 Manager
3 Support
4 Assistant
我想创建一个视图:
SELECT * FROM [MYVIEW]会给我以下数据:
1& 0将是位,以便我可以在UI显示屏上显示带有复选框的网格。
CustId Admin Manager Support Assistant
2 0 0 1 1
3 0 0 0 1
4 1 1 0 0
到目前为止,我不知道该怎么做。
答案 0 :(得分:6)
您是否阅读过Microsoft SQL Server 2005中PIVOT的文档?
SELECT CustId,
[1] AS Admin,
[2] AS Manager,
[3] AS Support,
[4] AS Assistant
FROM (SELECT c.CustId, r.RoleId
FROM CustomerRoles c JOIN Roles r USING (RoleId)) AS s
PIVOT (
COUNT(CustId)
FOR RoleId IN ([1], [2], [3], [4])
) AS pvt
ORDER BY CustId;
我没有测试过上面的内容,只是基于doc。这可能会让你开始。
似乎没有办法动态生成列。你必须对它们进行硬编码。
答案 1 :(得分:4)
试试这个:
SELECT
CustId,
SUM(ISNULL(Admin,0)) AS Admin,
SUM(ISNULL(Manager,0)) AS Manager,
SUM(ISNULL(Support,0)) AS Support,
SUM(ISNULL(Assistant,0)) AS Assistant
FROM
(
SELECT cr.CustId, cr.RoleId, Role, 1 AS a
FROM CustromerRoles cr
INNER JOIN Roles r ON cr.RoleId = r.RoleId
) up
PIVOT (MAX(a) FOR Role IN (Admin, Manager, Support, Assistant)) AS pvt
GROUP BY CustId
测试。它给出了你想要的相同结果。
答案 2 :(得分:2)
PIVOT的缺点是必须知道列,因为您必须在查询中提供ID。您可以使用动态SQL解决此问题,即在您的情况下根据Roles表中的单独查询结果动态生成PIVOT查询,然后执行结果。这可以在存储过程中轻松完成。
示例:
CREATE TABLE #CustomerRole ([CustId] int, [RoleId] int);
INSERT INTO #CustomerRole values (2, 4);
INSERT INTO #CustomerRole values (2, 3);
INSERT INTO #CustomerRole values (3, 4);
INSERT INTO #CustomerRole values (4, 1);
INSERT INTO #CustomerRole values (4, 2);
CREATE TABLE #Role ([Id] int, [Role] varchar(20));
INSERT INTO #Role values (1, 'Admin');
INSERT INTO #Role values (2, 'Manager');
INSERT INTO #Role values (3, 'Support');
INSERT INTO #Role values (4, 'Assistant');
DECLARE @RoleList nvarchar(MAX)
SELECT @RoleList = COALESCE(@RoleList + ',[' + [Role] + ']',
'[' + [Role] + ']')
FROM #Role;
DECLARE @SQL Nvarchar(max);
SET @SQL = 'SELECT
[CustId] ' +
ISNULL(', ' + @RoleList , '') + '
FROM #CustomerRole custrole
inner join #Role as r
on r.[Id] = custrole.[RoleId]
PIVOT (count([Id]) for [Role] IN
(' + ISNULL(@RoleList, '[No role]') +
')) as pvt;'
EXEC sp_executesql @SQL;
drop table #Role;
drop table #CustomerRole;