[英]How do I exclude entries from a recursive CTE?
如何使用Sqlite從遞歸CTW中排除條目?
CREATE TABLE GroupMembers (
group_id VARCHAR,
member_id VARCHAR
);
INSERT INTO GroupMembers(group_id, member_id) VALUES
('1', '10'),
('1', '20'),
('1', '30'),
('1', '-50'),
('2', '30'),
('2', '40'),
('3', '1'),
('3', '50'),
('4', '-10'),
('10', '50'),
('10', '60');
我想要一個查詢,該查詢將給我(遞歸)組中的成員列表。 但是,第一個字符為“-”的成員表示減號后的id不在組中。
例如,“ 1”的成員是“ 10”,“ 20”,“ 30”和“ -50”。 但是,“ 10”是一個組,因此我們需要添加其子級“ 50”和“ 60”。 但是,“-50”已經是成員,因此我們不能包含“ 50”。 總之,“ 1”的成員是“ 10”,“ 20”,“ 30”,“-50”和“ 60”。
看來此查詢應該工作:
WITH RECURSIVE members(id) AS (
VALUES('1')
UNION
SELECT gm.member_id
FROM members m
INNER JOIN GroupMembers gm ON mg.group_id=m.id
LEFT OUTER JOIN members e ON '-' || gm.member_id=e.id
WHERE e.id IS NULL
)
SELECT id FROM members;
但是我得到了錯誤: multiple references to recursive table: members
如何解決/重寫此功能以執行我想要的操作?
注意:結果集中是否返回“ -50”並不重要。
我沒有可用於測試的SQLite,但是假設-50
也意味着也應該排除50
,我想您正在尋找:
WITH RECURSIVE members(id) AS (
VALUES('1')
UNION
SELECT gm.member_id
FROM GroupMembers gm
JOIN members m ON gm.group_id=m.id
WHERE member_id not like '-%'
AND not exists (select 1
from groupMembers g2
where g2.member_id = '-'||gm.member_id)
)
SELECT id
FROM members;
(以上工作在Postgres中)
通常,您從遞歸部分的基表中進行選擇,然后選擇聯接回實際的CTE。 然后,通過常規的where
子句對不需要的行進行過濾, where
無需再次加入CTE。 遞歸CTE定義為在JOIN沒有找到更多行時終止。
SQLFiddle(Postgres): http ://sqlfiddle.com/#!15/04405/1
需求更改后進行編輯 (已進行了詳細說明):
因為您需要根據行的位置排除行(原始問題中未提供的詳細信息)。 只能在CTE 之外進行過濾。 同樣,我不能僅使用Postgres使用SQLite進行測試:
WITH RECURSIVE members(id, level) AS (
VALUES('4', 1)
UNION
SELECT gm.member_id, m.level + 1
FROM GroupMembers gm
JOIN members m ON gm.group_id=m.id
)
SELECT m.id, m.level
FROM members m
where id not like '-%'
and not exists (select 1
from members m2
where m2.level < m.level
and m2.id = '-'||m.id);
更新的SQLFiddle: http ://sqlfiddle.com/#!15/ec0f9/3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.