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

发布于 2024-09-04 11:27:08 字数 935 浏览 5 评论 0原文

我有一个非常简单的查询,需要进行数据透视,但我不知道如何从我在文献中读到的内容将其转换为数据透视表。我读过的所有内容都涉及硬编码列或太复杂。它必须更简单,否则我就无法掌握 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

任何线索都非常感激!

I have a very simple query that I need pivoted, but I haven't got a clue how to turn it into a pivot table from what I've read in the literature. Everything I've read involves hard-coded columns or is too complex. It has to be simpler, or I just can't grasp CTE's.

The query is a list of user names and clients they have access to. So I have something like:

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

The total number of clients could be around 20 or so. Some users can access all clients, others only one or two. What I want to see is:

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

This involves three tables: a user table, a client table, and a cross-reference table (permissions) that unites users with their clients.

I've tried something like the following, but it obviously doesn't work (or even compile).

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

Any clues most appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

万劫不复 2024-09-11 11:27:08

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

for client_code in (select client_code fromclients)

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

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

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;

I believe SQL server requires you to explicitly name each column in your pivot. So, the following snippet from your original query is not allowed:

for client_code in (select client_code from clients)

You would have to name each client code explicitly.

Edit: Here is a sample pivot to fit your example:

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

Edit: Here is a dynamic SQL option; you might put this in a 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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文