3

役割と権限の表があります。

role | permission    
r1   | p1
r2   | p1
r2   | p2
r3   | p1
r3   | p2
r3   | p3

私が欲しいのは、列が(ロール、次に各権限)である出力テーブルです。権限/役割のペアがテーブルに存在する場合は1が必要であり、存在しない場合は0が必要です。

出力は次のとおりです。

role | p1 | p2 | p3
r1   | 1  | 0  | 0
r2   | 1  | 1  | 0
r3   | 1  | 1  | 1

それは簡単ですが、ここにキッカーがあります...役割も権限も固定長ではなく、新しいものはいつでも追加できるので、これを考慮に入れる必要があります。

SQLの性質上、これは不可能だと思いますが、お願いしたいと思いました。

4

1 に答える 1

1

使用しているRDBMSを指定しなかったため、MySQLとSQLServerの両方のソリューションを次に示します。

MySQL:

これはですがPIVOT、MySQLにはPIVOT関数がないため、集計関数とCASEステートメントを使用して複製する必要があります。

静的バージョン-すべての値を事前に知っている場所です。

select role,
  sum(case when permission = 'p1' then 1 else 0 end) p1,
  sum(case when permission = 'p2' then 1 else 0 end) p2,
  sum(case when permission = 'p3' then 1 else 0 end) p3
from yourtable
group by role;

SQL FiddlewithDemoを参照してください

事前に列に変換する値がわからない場合は、プリペアドステートメントを使用できます。

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'sum(case when permission = ''',
      permission,
      ''' then 1 else 0 end) AS ',
      permission
    )
  ) INTO @sql
FROM yourtable;

SET @sql = CONCAT('SELECT role, ', @sql, ' 
                  FROM yourtable 
                   GROUP BY role');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SQL FiddlewithDemoを参照してください

SQLサーバー:

SQL ServerにはPIVOT関数があり、値をハードコーディングするか、動的SQLを使用できます。

静的バージョン:

select *
from 
(
  select role, permission
  from yourtable
) src
pivot
(
  count(permission)
  for permission in ([p1], [p2], [p3])
) piv;

SQL FiddlewithDemoを参照してください

動的バージョン:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(permission) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT role, ' + @cols + ' from 
             (
                select role, permission
                from yourtable
            ) x
            pivot 
            (
                count(permission)
                for permission in (' + @cols + ')
            ) p '

execute(@query)

SQL FiddlewithDemoを参照してください

すべてのバージョンの結果は次のとおりです。

| ROLE | P1 | P2 | P3 |
-----------------------
|   r1 |  1 |  0 |  0 |
|   r2 |  1 |  1 |  0 |
|   r3 |  1 |  1 |  1 |
于 2012-11-20T12:22:05.150 に答える