1

ピボットが必要な非常に単純なクエリがありますが、文献で読んだものからピボット テーブルに変換する方法の手がかりがありません。私が読んだものはすべて、ハードコードされた列が含まれているか、複雑すぎます。もっと単純にする必要があります。そうしないと、CTE を把握できません。

クエリは、アクセス権を持つユーザー名とクライアントのリストです。だから私は次のようなものを持っています:

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

クライアントの総数は、約 20 人程度である可能性があります。すべてのクライアントにアクセスできるユーザーもいれば、1 つまたは 2 つのクライアントにしかアクセスできないユーザーもいます。私が見たいのは:

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

これには、ユーザー テーブル、クライアント テーブル、およびユーザーとクライアントを結び付ける相互参照テーブル (権限) の 3 つのテーブルが含まれます。

私は次のようなことを試しましたが、明らかに動作しません (またはコンパイルさえしません)。

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

どんな手がかりも大歓迎です!

4

1 に答える 1

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;
于 2010-06-01T14:42:23.047 に答える