Sql server 如何为这个简单的案例创建透视查询?

Sql server 如何为这个简单的案例创建透视查询?,sql-server,sql-server-2005,common-table-expression,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

我有一个非常简单的查询,我需要数据透视,但我还不知道如何从我在文献中读到的内容将其转换为数据透视表。我读过的每一篇文章都涉及硬编码的专栏,或者过于复杂。它必须更简单,否则我就是不能掌握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

非常感谢任何线索

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

对于中的客户端代码,请从客户端中选择客户端代码

您必须显式地命名每个客户机代码

编辑:以下是适合您的示例的示例轴:

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;

谢谢Michael-这一定是为什么所有示例都明确地命名了列!这是一个真正的皮塔当你可以有几十个客户…同意。如果有许多客户端,可以将查询形成字符串并使用sp_executesql。我将很快更新我的答案。所以唯一的方法是使用动态sql?我已经看到了一些类似的例子。我试着使用你的上述方法,但不幸的是,我有成千上万的用户!这需要一段时间来编写代码。也许另一个答案是将用户/客户机列表导入Excel,然后让Excel创建透视表。Excel似乎在这方面做得更好。我不知道为什么拥有数千个用户很重要,因为每个用户都只是pivot中的一行。你也可以使用Excel;我想这取决于你需要查询数据的频率。非常感谢Michael!我能把你的答案翻译成我的真实案例,但有几个警告。首先,如果我必须在大约33000行中键入所有用户,那么用户的数量很重要,但如果我使用动态sql则不重要。其次,我的一个客户选择是ALL,出于某种无法解释的原因,它抛出了一个错误。如果我从客户机选项中删除所有选项,它将运行得非常好。奇怪的最后一个问题是,如果有权访问该客户机,是否可以将值字段中的客户机名称仅替换为X,或者将其替换为空而不是空?“不”是一个可以接受的答案。。。