我需要一些问题的帮助。
我正在使用SQL在Microsoft数据库上工作,并且有一个与此表类似的表:
|*Name*|*Permissions*|
|App1 |Permission 1 |
|App1 |Permission 2 |
|App1 |Permission 3 |
|App2 |Permission 1 |
|App2 |Permission 2 |
|App2 |Permission 3 |
因此这是一个m对n的关系,因为有多个权限分配给一个应用程序,但也有多个应用程序使用相同的权限。
我已经尝试过使用诸如以下这样的方法将表与其自身连接起来:
select distinct apps1.name, apps2.permissions from Apps apps1
join Apps apps2
where apps2.name IN
(SELECT distinct name from Apps);
但是它并没有给我我想要的结果。
我想要一个看起来像这样的结果
|*Name*|*Permission1*|*Permission2*|*Permission3*|
|App1 |Permission 1 |Permission 2 |Permission 3 |
|App2 |Permission 1 |Permission 2 |Permission 3 |
应用程序可能会获得不同数量的权限,但是如果是这样,则可以将这些空列填充为NULL值。
希望您能帮助我。 如果需要更多信息,请给我写信。由于我是StackOverflow的新手,所以我不是写下问题的专业人士。
答案 0 :(得分:1)
您可以为此使用PIVOT运算符。下面是一个示例。
CREATE TABLE #Permission
(
Name VARCHAR(10)
,Permission VARCHAR(25)
)
INSERT INTO #Permission (Name, Permission) VALUES
('App1', 'Permission 1')
,('App1', 'Permission 2')
,('App1', 'Permission 3')
,('App2', 'Permission 1')
,('App2', 'Permission 2')
,('App2', 'Permission 3')
,('App3', 'Permission 2');
SELECT *
FROM
(
SELECT Name, Permission FROM #Permission
) AS A
PIVOT
(
MAX(Permission)
FOR Permission IN ([Permission 1], [Permission 2], [Permission 3])
) AS PivotTable
DROP TABLE #Permission;
如果您具有 n 个权限,则可能必须使用dynamic pivoting。
答案 1 :(得分:0)
如果您拥有最多的权限(例如三个),则可以使用条件聚合(或pivot
):
select a.name,
max(case when seqnum = 1 then a.permission end) as permission_1,
max(case when seqnum = 2 then a.permission end) as permission_2,
max(case when seqnum = 3 then a.permission end) as permission_3
from (select a.*,
row_number() over (partition by a.name order by a.name) as seqnum
from apps a
) a
group by a.name;
如果您不知道要返回多少列,则需要使用动态SQL,查询会更加复杂。
答案 2 :(得分:0)
您可以使用PIVOT
进行此类查询:
一个模拟场景的
DECLARE @mockupTable TABLE([Name] VARCHAR(100),[Permissions] VARCHAR(100));
INSERT INTO @mockupTable VALUES
('App1','Permission 1')
,('App1','Permission 2')
,('App1','Permission 3')
,('App2','Permission 1')
,('App2','Permission 2')
,('App2','Permission 3');
-查询
SELECT p.*
FROM
(
SELECT t.*
,CONCAT('Permission',ROW_NUMBER() OVER(PARTITION BY t.[Name] ORDER BY t.[Permissions])) AS ColumnName
FROM @mockupTable t
) tbl
PIVOT
(
MAX(tbl.[Permissions])
FOR tbl.ColumnName
IN(Permission1,Permission2,Permission3,Permission4 /*add as many as you need*/)
) p;
简而言之:
使用CONCAT
和ROW_NUMBER
,我们可以创建一个值,以后将其用作数据透视表的列名。
答案 3 :(得分:0)
;with cte as (
SELECT *
,ROW_NUMBER() over(partition by Name order by Permissions ) rn
FROM YourTable
)
select Name
,MAX(case when rn=1 then Permissions end) Permission1
,MAX(case WHEN rn=2 then Permissions end) Permission2
,MAX(case WHEN rn=3 then Permissions end) Permission3
FROM cte
group by Name