SQL Server Find a list of users with the same set of permission groups

06odsfpq  于 2023-03-07  发布在  其他
关注(0)|答案(1)|浏览(80)

We are adding Roles to our system for our security setup.

We are trying take our main UserItems table to find a list of users with the same set of permission groups so that we can suggest to the end user what roles should be setup and with what permission groups.

Here is the table setup:

CREATE TABLE [dbo].[UserItems](
    [UserItemId] [int] IDENTITY(1,1) NOT NULL,
    [UserId] [int] NOT NULL,
    [PermissionGroupId] [int] NULL,
    [CanModify] [bit] NOT NULL,
    [ItemOrganizationId] [int] NOT NULL,
    [SortOrder] [int] NOT NULL,
 CONSTRAINT [PK_UserItem] PRIMARY KEY CLUSTERED 
(
    [UserItemId] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

I've tried several SQL statements, I'm having no luck.

I'm trying to obtain a list of users with the same set of permission groups, so we can determine possible roles based on what the customer has set up for the UserItems.

SELECT        COUNT(*) AS TotalUsers, dbo.UserItems.PermissionGroupId,      dbo.PermissionGroups.PermissionGroupName
     FROM            dbo.UserItems INNER JOIN
                         dbo.PermissionGroups ON dbo.UserItems.PermissionGroupId =    dbo.PermissionGroups.PermissionGroupId
    GROUP BY  dbo.UserItems.PermissionGroupId,  dbo.PermissionGroups.PermissionGroupName
    HAVING        (COUNT(*) > 1)
    ORDER BY TotalUsers DESC

    SELECT        COUNT(*) AS TotalUsers,  dbo.UserEndItems.PermissionGroupId
FROM            dbo.UserItems
    Group by dbo.UserItems.PermissionGroupId
    HAVING        (COUNT(*) > 1)
    ORDER BY TotalUsers DESC

How can I obtain a list of users with the same set of permissions groups so that we can make roles based on that data?

UserItemIdUserIdPermissionGroupIdCanModifyItemOrganizationIdSortOrder
1228420150014
2228426043955
3228426051525
4228426051545
5228426048615
6228426043945
7228426044420
8228426051025
9228426051005
10228419041455
11228420041020
12228423041120
13228419040980
14228426042240
15228426057853
16228499066170
17228499066190
18228499066210
19228499066230
20107499166170
21107499066190
22107499066210
23107499066230
24228426069700
25108426043950
26108426051520
27108426051540
28108426048610
29108426043940
30108426044420
31108426051020
32108426051000
33108426042240
34108426057850
35108426069700
36137426043950
37137426051520
38137426051540
39137426048610
40137426043940
41137426044420
42137426051020
43137426051000
44137426042240
45137426057850
46137426069700
47107426043950
48107426051520
49107426051540
50107426048610
51107426043940
52107426044420
53107426051020
54107426051000
55107426042240
56107426057850
57107426069700
58235426043950
59235426051520
60235426051540
61235426048610
62235426043940
63235426044420
64235426051020
65235426051000
66235426042240
67235426057850
68235426069700
69228442057380
70228442057410
71107531071110
72107531071130
73107531071150
74107531071170
75222426069700
76222531071110
77222531071130
78222531071150
79222531071170
80222499066170
81222499066190
82222426057850
83222426043940
84222426043950
85222426044420
86222426048610
87222426051000
88222426051020
89222426051520
90222426051540
91222499066230
92222499066210
93222426042240
94228421049830
95228421042250
96228421041420
97228421042850
98228421041440
99228421041410
100228421040990
101228421159730
102228424041120
103228424041020
104228424040950
105228424041010
106228424040990
107228424040960
108228424040980
109228424042240
110228424045790
111228424045860
112228418045790
113228418054430
114107499057840
115222499057840
116197418045790
117197418054430
118197419041450
119197419040980
120197420050010
121197420041020
122197421059730
123197421041410
124197421049830
125197421040990
126197421041420
127197421041440
128197421042250
129197421042850
130197423041120
131197424045860
132197424045790
133197424041120
134197424042240
135197424040990
136197424040980
137197424041350
138197424040950
139197424040960
140197424041060
141197424041020
142197424041000
143197424041010
144197426051020
145197426051520
146197426051540
147197426051000
148197426044420
149197426043940
150197426043950
151197426057850
152197426048610
153197426042240
154197426069700
155197442057410
156197442057380
157197499066230
158197499066210
159197499066170
160197499066190
161197499057840
162197531071110
163197531071130
164197531071150
165197531071170
166197419062930
167228419162930
168277424041350
169277424041120
170277424041020
171277424040950
172277424041010
173277424041060
174277424040990
175277424040960
176277424041000
177277424040980
178277424042240
179277424045790
180277424045860
181198418045790
182198418054430
183198419040980
184198419041450
185198419062930
186198420050010
187198420041020
188198421042850
189198421041410
190198421041420
191198421041440
192198421042250
193198421059730
194198421040990
195198421049830
196198423041120
197198424041060
198198424041350
199198424040990
200198424040950
201198424040980
202198424041010
203198424042240
204198424041020
205198424041000
206198424045860
207198424045790
208198424041120
209198426043940
210198426043950
211198426048610
212198426051540
213198426051000
214198426042240
215198426051520
216198426051020
217198426057850
218198426044420
219198426069700
220198442057380
221198442057410
222198499066170
223198499066190
224198499066210
225198499066230
226198499057840
227198531071170
228198531071150
229198531071130
230198531071110
231235428042800
232235428052350
233235428044420
234235428069700
235277421049830
236277421042250
237277421041420
238277421042850
239277421041440
240277421041410
241277421040990
242277421059730
243288418045790
244288418054430
245288419040980
246288419041450
247288419062930
248288420050010
249288420041020
s5a0g9ez

s5a0g9ez1#

As suggested by @NickW early in the comments:

After eliminating duplicate UserId / PermissionGroupId combinations, you can group by UserId and use STRING_AGG() to gather the PermissionGroupId values into an ordered comma separated list. After that, you can then group those results by combined group IDs and aggregate the UserIDs having the same group ID collection.

;WITH DistinctUserGroups AS (
    SELECT DISTINCT UEI.UserId, UEI.PermissionGroupId
    FROM UserEndItems UEI
),
UserGroupsCombined AS (
    SELECT
        DUG.UserId,
        COUNT(*) AS NGroups,
        STRING_AGG(DUG.PermissionGroupId, ',')
            WITHIN GROUP(ORDER BY DUG.PermissionGroupId)
            AS GroupIdList
    FROM DistinctUserGroups DUG
    GROUP BY DUG.UserId
)
SELECT
    COUNT(*) AS NUsers,
    STRING_AGG(UGC.UserId, ',')
        WITHIN GROUP(ORDER BY UGC.UserId)
        AS UserIdList,
    UGC.NGroups,
    UGC.GroupIdList
FROM UserGroupsCombined UGC
GROUP BY UGC.NGroups, UGC.GroupIdList
ORDER BY UGC.GroupIdList

Sample results:

NUsersUserIdListNGroupsGroupIdList
12883418,419,420
12289418,419,420,421,423,424,426,442,499
2197,19810418,419,420,421,423,424,426,442,499,531
12772421,424
2108,1371426
12352426,428
2107,2223426,499,531

See this db<>fiddlw .

Your sample data did not include the PermissionGroups table so the above just shows IDs. It should be a simple matter to include group names instead. You can also add HAVING conditions to eliminate singletons at both levels.

相关问题