如何为这个简单的案例创建一个Pivot查询?

时间:2010-06-01 14:34:25

标签: sql-server sql-server-2005 common-table-expression

我有一个非常简单的查询,我需要转动,但我还没有弄清楚如何将其转换为我在文献中读到的数据透视表。我读过的所有内容都涉及硬编码列或太复杂。它必须更简单,或者我无法掌握CTE。

查询是他们有权访问的用户名和客户的列表。所以我有类似的东西:

user  client
1 a
1 b
1 c
2 a
2 d
3 a
3 d
3 e
3 f

客户总数约为20左右。有些用户可以访问所有客户,其他用户只能访问一两个。我想看到的是:

user a b c d e f
1 x x x
2 x   x
3 x   x x x

这涉及三个表:用户表,客户端表和将用户与其客户结合在一起的交叉引用表(权限)。

我尝试了类似下面的内容,但它显然不起作用(甚至编译)。

with usersclients(user_name, clients, client_code)
as
(
 select users.user_name
 from clients cli
  left join
  (select u.user_id, user_name, c.client_id, client_code, client_name 
   from permissions p inner join clients c on p.client_id = c.client_id
   inner join users u on u.user_id = p.user_id
  ) user
  on user.client_id = cli.client_id
)
select *
from usersclients
pivot (max(client_code) for client_code in (select client_code from clients)) as P

最感谢的任何线索!

1 个答案:

答案 0 :(得分:2)

我相信SQL服务器要求您明确命名数据透视表中的每一列。因此,不允许使用原始查询中的以下代码段:

for client_code in (select client_code from clients)

您必须明确命名每个客户端代码。

编辑:这是一个适合您示例的示例枢轴:

WITH Permit (Usr, Client) AS
(
    SELECT 1, 'a' UNION ALL
    SELECT 1, 'b' UNION ALL
    SELECT 1, 'c' UNION ALL
    SELECT 2, 'a' UNION ALL
    SELECT 2, 'd' UNION ALL
    SELECT 3, 'a' UNION ALL
    SELECT 3, 'd' UNION ALL
    SELECT 3, 'e' UNION ALL
    SELECT 3, 'f'
)
SELECT p.*
FROM Permit
    PIVOT (MAX(Client) FOR Client IN (a, b, c, d, e, f)) p

编辑:这是一个动态SQL选项;你可以把它放在TVF中:

--source table
CREATE TABLE #Permit (Usr int, Client char(1));
INSERT INTO #Permit (Usr, Client)
SELECT 1, 'a' UNION ALL
SELECT 1, 'b' UNION ALL
SELECT 1, 'c' UNION ALL
SELECT 2, 'a' UNION ALL
SELECT 2, 'd' UNION ALL
SELECT 3, 'a' UNION ALL
SELECT 3, 'd' UNION ALL
SELECT 3, 'e' UNION ALL
SELECT 3, 'f';


DECLARE @Command nvarchar(max);
SET @Command = '';

--prepare the list of columns
SELECT @Command = @Command + ', ' + CONVERT(nvarchar(10), Client)
FROM (SELECT DISTINCT Client FROM #Permit) x;

--chop the extra leading comma off
SET @Command = SUBSTRING(@Command, 3, LEN(@Command));

--prepare the rest of the pivot command
SET @Command = N'
SELECT p.*
FROM #Permit
    PIVOT (MAX(Client) FOR Client IN (' + @Command + ')) p';

--execute the command
EXEC sp_executesql @Command;


DROP TABLE #Permit;