sql - 如果 parent_id 已经存在,如何查找和删除 child_id
问题描述
我在父子和扁平结构中都有 2 个层次结构数据表
父子表:
PARENT_ID CHILD_ID
1234 1111
1234 2222
1234 3333
3333 33XX
3333 33YY
扁平结构:
LEVEL_1 LEVEL_2 LEVEL_3
1234 1111
1234 2222
1234 3333 33XX
1234 3333 33YY
我有另一个用户表,其中包含哪个用户可以访问哪个 ID
USER_ID USER_ACCESS
USER_A 1234,1111
USER_B 33YY,3333,1234
我已将上表进一步转换为以下格式
USER_ID USER_ACCESS
USER_A 1234
USER_A 1111
USER_B 33YY
USER_B 3333
USER_B 1234
如果他的 ID 已经存在 parent_id,我需要为每个用户查找并删除 child_id
上述示例输出
USER_ID USER_ACCESS
USER_A 1234
USER_B 1234
在 Oracle/SQL Server 中需要一个解决方案,避免任何循环。
解决方案
先说几点:
拥有层次结构已经使对扁平结构的需求过时了。此外,扁平表永远无法容纳层次结构的所有级别。您添加的每个级别都需要您添加一个额外的列,这很可笑。
以您需要用逗号分隔键的方式存储用户访问权限,使您没有(好的)方法来验证表之间的约束。
话虽这么说(并使用不需要字符串拆分的表):
DROP TABLE IF EXISTS #struct_info;
CREATE TABLE #struct_info (
PARENT_ID VARCHAR(50),
CHILD_ID VARCHAR(50)
);
DROP TABLE IF EXISTS #access_info;
CREATE TABLE #access_info (
USER_ID VARCHAR(50),
USER_ACCESS VARCHAR(50)
);
INSERT INTO #struct_info
(
PARENT_ID,
CHILD_ID
)
VALUES
('1234','1111'),
('1234','2222'),
('1234','3333'),
('3333','33XX'),
('3333','33YY')
INSERT INTO #access_info
(
USER_ID,
USER_ACCESS
)
VALUES
('USER_A','1234'),
('USER_A','1111'),
('USER_B','33YY'),
('USER_B','3333'),
('USER_B','1234')
SELECT * FROM #struct_info
SELECT * FROM #access_info
;WITH cte AS (
SELECT
PARENT_ID,
CHILD_ID
FROM #struct_info
UNION ALL
SELECT
cte.PARENT_ID,
si.CHILD_ID
FROM cte
INNER JOIN #struct_info si
ON si.PARENT_ID = cte.CHILD_ID
)
DELETE ai
FROM #access_info ai
WHERE EXISTS (
SELECT 1
FROM cte
WHERE cte.CHILD_ID = ai.USER_ACCESS
AND EXISTS (SELECT 1
FROM #access_info ai2
WHERE ai2.USER_ID = ai.USER_ID
AND ai2.USER_ACCESS = cte.PARENT_ID)
)
SELECT * FROM #access_info
cte 确定所有可能的层次结构变体 delete 查找可以在该变体中找到父级的任何 child_id
推荐阅读
- matlab - 防止彩条在 MATLAB 中调整图像大小
- angular - 如何在 Angular 的 Rxjs 6 中使用运算符
- javascript - javascript中表单提交的返回方法
- android - 生成请求代码时未显示通知
- ios - 在 iOS 和 macOS 玩家之间使用 GameCenter 启用多人游戏
- bash - 简单的 shell 脚本程序中的错误
- javascript - 为什么带有 Vue.js 的 Webpack 会产生这么大的构建文件?
- php - PHP DateTime diff 返回错误的差异
- html - 文本输入上的 CSS 渐变
- angular - ngFor 中的动态 ngModel 不起作用