实体A配置权限时,有以下维度:
产品线数据有:查询接口测试一级产品类别、查询接口测试二级产品类别、查询接口测试三级产品类别
服务网点数据有:查询接口测试网点1、查询接口测试网点2、查询接口测试网点3
部门数据有(负责人维度):查询接口测试上级部门、查询接口测试下级部门
以上数据都有上下级关系
用户“张三”的基础信息中,部门是查询接口测试上级部门,服务网点是查询接口测试网点2,产品线是查询接口测试一级产品类别
实体A数据表如下:
id | name | owningbusinessunit | ptest_workstation | ptest_productline |
1 | 实体1 | 查询接口测试上级部门 | ||
2 | 实体2 | 查询接口测试下级部门 | ||
3 | 实体3 | 查询接口测试网点1 | ||
4 | 实体4 | 查询接口测试网点2 | ||
5 | 实体5 | 查询接口测试网点3 | ||
6 | 实体6 | 一级产品类别 | ||
7 | 实体7 | 二级产品类别 | ||
8 | 实体8 | 三级产品类别 |
配置“张三”三个维度的权限都为“本部门及下级部门”,读权限举例:
可查询到一级、二级、三级产品类别的数据,即上表中的6、7、8
可查询到测试网点2、测试网点3的数据,即上表中的4、5
可查询到上级部门、下级部门的数据,即上表中的1、2
(因为几个维度的权限走的是并集,所以上表中,空白字段不论填什么值,都不影响读权限举例的逻辑)
三个维度一起查询,sql会很长,不便于理解,所以拆分开,每个维度都查询一下count(*),查询后汇总,跟接口返回的totalcount对比是否一致
WITH RECURSIVE DepartmentHierarchy AS (
-- 锚点成员:从部门A开始
SELECT new_srv_stationid
FROM new_srv_station
WHERE new_srv_stationid = (select new_stationid from systemuser where domainname = 'zhangsan') -- 假设通过部门名称定位部门A
UNION ALL
-- 递归成员:找到下级部门
SELECT d.new_srv_stationid
FROM new_srv_station d
INNER JOIN DepartmentHierarchy dh ON d.new_superiorstation_id = dh.new_srv_stationid
)
-- 查询部门A及其下级部门的所有订单
SELECT o.ptest_duoweiduid
FROM ptest_duoweidu o
JOIN DepartmentHierarchy dh ON o.ptest_workstation = dh.new_srv_stationid;
WITH RECURSIVE DepartmentHierarchy AS (
-- 锚点成员:从部门A开始
SELECT businessunitid
FROM businessunit
WHERE businessunitid = (select businessunitid from systemuser where domainname = 'zhangsan') -- 假设通过部门名称定位部门A
UNION ALL
-- 递归成员:找到下级部门
SELECT d.businessunitid
FROM businessunit d
INNER JOIN DepartmentHierarchy dh ON d.parentbusinessunitid = dh.businessunitid
)
-- 查询部门A及其下级部门的所有订单
SELECT o.ptest_duoweiduid
FROM ptest_duoweidu o
JOIN DepartmentHierarchy dh ON o.owningbusinessunit = dh.businessunitid;
WITH RECURSIVE DepartmentHierarchy AS (
-- 锚点成员:从部门A开始
SELECT new_productgroupid
FROM new_productgroup
WHERE new_productgroupid in (select new_productgroupid from new_productgroupusers where systemuseridname = '张三') -- 假设通过部门名称定位部门A
UNION ALL
-- 递归成员:找到下级部门
SELECT d.new_productgroupid
FROM new_productgroup d
INNER JOIN DepartmentHierarchy dh ON d.new_parentgroup_id = dh.new_productgroupid
)
-- 查询部门A及其下级部门的所有订单
SELECT o.ptest_duoweiduid
FROM ptest_duoweidu o
JOIN DepartmentHierarchy dh ON o.ptest_productline = dh.new_productgroupid;
用这种方法断言,最后确实数据对得上,但是其实是错误的, 增加几条实体A的数据:
id | name | owningbusinessunit | ptest_workstation | ptest_productline |
1 | 实体1 | 查询接口测试上级部门 | ||
2 | 实体2 | 查询接口测试下级部门 | ||
3 | 实体3 | 查询接口测试网点1 | ||
4 | 实体4 | 查询接口测试网点2 | ||
5 | 实体5 | 查询接口测试网点3 | ||
6 | 实体6 | 一级产品类别 | ||
7 | 实体7 | 二级产品类别 | ||
8 | 实体8 | 三级产品类别 | ||
9 | 实体9 | 查询接口测试上级部门 | 查询接口测试网点2 | |
10 | 实体10 | 查询接口测试上级部门 | 一级产品类别 | |
11 | 实体11 | 查询接口测试网点3 | 二级产品类别 |
三种维度查询
负责人维度:查询count=4,实际为实体1、2、9、10
服务网点维度:查询count=4,实际为实体4、5、9、11
产品线维度:查询count=5,实际为实体6、7、8、10、11
汇总count=13,实际接口返回的totalcount=10
分析发现,业务数据实体9、10、11都重复计算了一次,导致汇总count多了3,所以分开汇总count不可取,没办法去重
三个维度的查询出业务数据的id,汇总id后再去重,最后再计数:
WITH RECURSIVE DepartmentHierarchy1 AS (
-- 第一个递归查询:基于new_srv_station
SELECT new_srv_stationid
FROM new_srv_station
WHERE new_srv_stationid = (SELECT new_stationid FROM systemuser WHERE domainname = 'zhangsan')
UNION ALL
SELECT d.new_srv_stationid
FROM new_srv_station d
INNER JOIN DepartmentHierarchy1 dh ON d.new_superiorstation_id = dh.new_srv_stationid
),
DepartmentHierarchy2 AS (
-- 第二个递归查询:基于businessunit
SELECT businessunitid
FROM businessunit
WHERE businessunitid = (SELECT businessunitid FROM systemuser WHERE domainname = 'zhangsan')
UNION ALL
SELECT d.businessunitid
FROM businessunit d
INNER JOIN DepartmentHierarchy2 dh ON d.parentbusinessunitid = dh.businessunitid
),
DepartmentHierarchy3 AS (
-- 第三个递归查询:基于new_productgroup
SELECT new_productgroupid
FROM new_productgroup
WHERE new_productgroupid IN (
SELECT new_productgroupid FROM new_productgroupusers WHERE systemuseridname = '张三'
)
UNION ALL
SELECT d.new_productgroupid
FROM new_productgroup d
INNER JOIN DepartmentHierarchy3 dh ON d.new_parentgroup_id = dh.new_productgroupid
),
-- 汇总查询结果并去重
Uniqueptest_duoweiduids AS (
SELECT o.ptest_duoweiduid
FROM ptest_duoweidu o
JOIN DepartmentHierarchy1 dh1 ON o.ptest_workstation = dh1.new_srv_stationid
UNION
SELECT o.ptest_duoweiduid
FROM ptest_duoweidu o
JOIN DepartmentHierarchy2 dh2 ON o.owningbusinessunit = dh2.businessunitid
UNION
SELECT o.ptest_duoweiduid
FROM ptest_duoweidu o
JOIN DepartmentHierarchy3 dh3 ON o.ptest_productline = dh3.new_productgroupid
)
-- 计算非重复的ptest_duoweiduid的数量
SELECT COUNT(DISTINCT ptest_duoweiduid) AS unique_count
FROM Uniqueptest_duoweiduids;
再优化下结构:
WITH RECURSIVE UserValues AS (
SELECT
new_stationid,
businessunitid,
new_productgroupid
FROM systemuser
WHERE domainname = 'zhangsan'
),
DepartmentHierarchy AS (
-- 锚点成员:从部门A开始
SELECT 'station' AS type, new_srv_stationid AS id
FROM new_srv_station
WHERE new_srv_stationid = (SELECT new_stationid FROM UserValues)
UNION ALL
SELECT 'station' AS type, d.new_srv_stationid
FROM new_srv_station d
INNER JOIN DepartmentHierarchy dh ON d.new_superiorstation_id = dh.id
UNION ALL
SELECT 'businessunit' AS type, businessunitid AS id
FROM businessunit
WHERE businessunitid = (SELECT businessunitid FROM UserValues)
UNION ALL
SELECT 'businessunit' AS type, d.businessunitid
FROM businessunit d
INNER JOIN DepartmentHierarchy dh ON d.parentbusinessunitid = dh.id
UNION ALL
SELECT 'productgroup' AS type, new_productgroupid AS id
FROM new_productgroup
WHERE new_productgroupid IN (SELECT new_productgroupid FROM new_productgroupusers WHERE systemuseridname = '张三')
UNION ALL
SELECT 'productgroup' AS type, d.new_productgroupid
FROM new_productgroup d
INNER JOIN DepartmentHierarchy dh ON d.new_parentgroup_id = dh.id
),
Uniqueptest_duoweiduids AS (
SELECT o.ptest_duoweiduid
FROM ptest_duoweidu o
JOIN DepartmentHierarchy dh ON (
(dh.type = 'station' AND o.ptest_workstation = dh.id) OR
(dh.type = 'businessunit' AND o.owningbusinessunit = dh.id) OR
(dh.type = 'productgroup' AND o.ptest_productline = dh.id)
)
)
SELECT COUNT(DISTINCT ptest_duoweiduid) AS unique_count
FROM Uniqueptest_duoweiduids;
以上方法查询出的数据可以和接口返回的totalcount对上