【发布时间】:2019-03-16 09:29:31
【问题描述】:
我遇到的问题是已删除的数据稍后仍会出现在同一查询中。自然,在完全独立的查询中,被删除的数据不会出现。
这不是我的用例,但我认为这是显示问题的最简单方法:
CREATE TABLE company (id INT PRIMARY KEY, name TEXT);
CREATE TABLE employee (id INT PRIMARY KEY, company_id INT REFERENCES company(id), name TEXT);
INSERT INTO company VALUES (1, 'first company');
INSERT INTO company VALUES (2, 'second company');
INSERT INTO employee VALUES (1, 1, 'first employee');
INSERT INTO employee VALUES (2, 2, 'second employee');
-- this select can successfully query for the data which has just been deleted
WITH deleted_employee AS (DELETE FROM employee WHERE id = 1 RETURNING id)
SELECT id, name FROM employee JOIN deleted_employee USING (id);
-- this select shows it has been deleted
SELECT * FROM employee;
我已经把它放入小提琴here。
似乎DELETE 直到整个查询完成才提交,这感觉很奇怪,因为优先级要求DELETE 出现在SELECT 之前。
有没有办法在单个查询中实现这一点?
编辑
答案已经回答了直接问题。根本问题是删除员工,然后删除其关联公司,如果没有更多员工与该公司关联。
这是我认为可以解决问题的查询:
WITH affected_company AS (DELETE FROM employee WHERE id = 1 RETURNING company_id)
DELETE FROM company
USING affected_company
WHERE NOT EXISTS (
SELECT 1
FROM employee
WHERE company_id = affected_company.company_id
);
SELECT * FROM company;
SELECT * FROM employee;
还有更新的fiddle。
您可以看到公司没有被删除。
【问题讨论】:
-
您到底想达到什么目的?如果您只想查看已删除的行,那么 Johey 的答案可能就是您正在寻找的。如果没有,那么您需要更详细地描述您的实际需求
-
我最初只是想了解发生了什么,以避免被灌输解决我的确切问题的方法。我现在更新了,我理解得更好了。
-
我明白这一点,您尝试创建一个简单的独立示例是值得称赞的(很少在问题上投入那么多精力),但在这种情况下需要更多细节;)
-
我认为不可能通过一个查询在多个表中删除,但如果是这样,我很乐意学习如何做到这一点。也许作为一种解决方法,您可以使用两个用分号分隔的查询来做到这一点?
-
@johey 我也不认为有一个很好的解决方案。我发布了一个不太好的解决方案,它适用于我编辑中描述的确切场景,仅用于教育目的! :)
标签: sql postgresql common-table-expression sql-delete