好的,讓我們做一些數據吧!
DECLARE @User TABLE
(
Perm INT,
User1 INT,
User2 INT,
User3 INT,
User4 INT,
User5 INT,
User6 INT,
User7 INT,
User8 INT,
User9 INT,
User10 INT
)
INSERT INTO @User
(Perm, User1, User2, User3, User4, User5, User6, User7, User8, User9, User10)
VALUES
(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
(2, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1),
(3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(4, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0),
(5, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1),
(6, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1),
(7, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1),
(8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(9, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1);
現在我們有一個表中的權限和用戶,現在我們做一些計數並且創建一個分組值。
SELECT
u.Perm,
u.User1,
u.User2,
u.User3,
u.User4,
u.User5,
u.User6,
u.User7,
u.User8,
u.User9,
u.User10,
CASE WHEN u.User1 = 1 THEN 1 ELSE 0 END +
CASE WHEN u.User2 = 1 THEN 2 ELSE 0 END +
CASE WHEN u.User3 = 1 THEN 4 ELSE 0 END +
CASE WHEN u.User4 = 1 THEN 8 ELSE 0 END +
CASE WHEN u.User5 = 1 THEN 16 ELSE 0 END +
CASE WHEN u.User6 = 1 THEN 32 ELSE 0 END +
CASE WHEN u.User7 = 1 THEN 64 ELSE 0 END +
CASE WHEN u.User8 = 1 THEN 128 ELSE 0 END +
CASE WHEN u.User9 = 1 THEN 256 ELSE 0 END +
CASE WHEN u.User10 = 1 THEN 512 ELSE 0 END AS GroupMe
FROM @User u
這裏是輸出:
Perm User1 User2 User3 User4 User5 User6 User7 User8 User9 User10 GroupMe
1 1 1 1 1 1 1 1 1 1 1 1023
2 1 1 0 0 0 0 0 1 1 1 899
3 1 0 0 0 0 0 0 0 0 0 1
4 1 1 1 1 0 0 0 0 0 0 15
5 1 1 0 0 0 0 0 1 1 1 899
6 1 1 0 0 0 0 0 0 1 1 771
7 0 0 1 1 1 1 1 0 1 1 892
8 1 0 0 0 0 0 0 0 0 0 1
9 1 0 1 1 0 1 1 0 1 1 877
你會看到,3和8具有相同的值。 另外2和5具有相同的值。
好吧,讓我們用數字表中添加燙髮突破區域:
;WITH
a AS (SELECT 1 AS i UNION ALL SELECT 1),
b AS (SELECT 1 AS i FROM a AS x, a AS y),
c AS (SELECT 1 AS i FROM b AS x, b AS y),
d AS (SELECT 1 AS i FROM c AS x, c AS y),
e AS (SELECT 1 AS i FROM d AS x, d AS y),
f AS (SELECT 1 AS i FROM e AS x, e AS y),
numbers AS
(
SELECT TOP(10)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS number
FROM f
), PrivBreakout AS
(
SELECT 1 AS UserId, u.Perm
FROM @User u
WHERE u.User1 = 1
UNION
SELECT 2 AS UserId, u.Perm
FROM @User u
WHERE u.User2 = 1
UNION
SELECT 3 AS UserId, u.Perm
FROM @User u
WHERE u.User3 = 3
UNION
SELECT 4 AS UserId, u.Perm
FROM @User u
WHERE u.User4 = 1
UNION
SELECT 5 AS UserId, u.Perm
FROM @User u
WHERE u.User5 = 1
UNION
SELECT 6 AS UserId, u.Perm
FROM @User u
WHERE u.User6 = 1
UNION
SELECT 7 AS UserId, u.Perm
FROM @User u
WHERE u.User7 = 1
UNION
SELECT 8 AS UserId, u.Perm
FROM @User u
WHERE u.User8 = 1
UNION
SELECT 9 AS UserId, u.Perm
FROM @User u
WHERE u.User9 = 1
UNION
SELECT 10 AS UserId, u.Perm
FROM @User u
WHERE u.User10 = 1
), ThreeLayerCombo AS
(
SELECT
a.number AS priva,
b.number AS privb,
c.number AS privc
FROM numbers a
CROSS JOIN numbers b
CROSS JOIN numbers c
WHERE b.number > a.number
AND c.number > b.number
)
在上面的代碼
現在,我決定去尋找至少3權限的組合
SELECT t.priva, t.privb, t.privc, COUNT(DISTINCT a.UserId) AS Grouper
FROM ThreeLayerCombo t
INNER JOIN PrivBreakout a
ON t.priva = a.Perm
INNER JOIN PrivBreakout b
ON b.UserId = a.UserId
AND t.privb = b.Perm
INNER JOIN PrivBreakout c
ON c.UserId = a.UserId
AND t.privc = c.Perm
GROUP BY t.priva, t.privb, t.privc
ORDER BY COUNT(DISTINCT a.UserId) DESC
讓我們看看對於最好的組合,這裏是輸出:
priva privb privc Grouper
1 2 5 5
1 7 9 5
2 5 6 4
1 2 6 4
1 5 6 4
1 2 9 3
2 5 9 3
1 5 9 3
1 6 9 3
2 6 9 3
5 6 9 3
5 7 9 2
5 6 7 2
4 5 6 2
2 7 9 2
6 7 9 2
1 4 9 2
1 6 7 2
2 6 7 2
2 5 7 2
2 4 5 2
2 4 6 2
1 2 7 2
1 5 7 2
1 2 4 2
1 4 5 2
1 4 6 2
1 4 7 1
1 4 8 1
1 2 3 1
1 5 8 1
1 2 8 1
1 3 4 1
1 3 5 1
1 3 6 1
1 3 8 1
1 3 9 1
2 4 8 1
2 4 9 1
2 5 8 1
2 6 8 1
1 6 8 1
1 8 9 1
2 3 4 1
2 3 5 1
2 3 6 1
2 3 8 1
2 3 9 1
6 8 9 1
2 8 9 1
3 4 5 1
3 4 6 1
3 4 8 1
3 4 9 1
3 5 6 1
3 5 8 1
3 5 9 1
3 6 8 1
3 6 9 1
3 8 9 1
4 5 8 1
4 5 9 1
4 6 8 1
4 6 9 1
4 7 9 1
4 8 9 1
5 6 8 1
5 8 9 1
從輸出最好的賭注是(1,2,5)和(1,7,9)建立特定的角色。
希望這會有所幫助!
對這些理論有一點挖掘,但它們令人難以置信,但是,我認爲它們對於我的小數據集來說太過先進了。 – gfroese
(錯過了我的編輯窗口) 感謝您提供的信息,我想我希望得到一個簡單的算法,您可以在兩個組及其關聯中提供各種可能的方法,以最有效地對這些關聯進行分類。我認爲我要做的只是嘗試在大網格中將這些關係可視化,並手動將相似的用戶在網格中彼此靠近,然後手動創建組。 – gfroese
在做了更多的閱讀之後,我偶然發現了這個令人驚奇的[library](http://www.philippe-fournier-viger.com/spmf/index.php?link=documentation.php#example1),它正是我所需要的。謝謝! – gfroese