通常将子查询转换为连接是相对简单的,但是这种情况一直困扰着我。给定
CREATE TABLE pages(
id serial PRIMARY KEY NOT NULL,
name TEXT NOT NULL,
category_id INT NOT NULL,
some_setting CHAR(50)
);
INSERT INTO pages (name, category_id, some_setting) VALUES ('a', 10, 'lorem');
INSERT INTO pages (name, category_id, some_setting) VALUES ('b', 10, 'lorem');
INSERT INTO pages (name, category_id, some_setting) VALUES ('invalid', 10, 'true');
INSERT INTO pages (name, category_id, some_setting) VALUES ('a', 20, 'lorem');
INSERT INTO pages (name, category_id, some_setting) VALUES ('b', 20, 'lorem');
INSERT INTO pages (name, category_id, some_setting) VALUES ('invalid', 20, 'false');
INSERT INTO pages (name, category_id, some_setting) VALUES ('a', 30, 'lorem');
INSERT INTO pages (name, category_id, some_setting) VALUES ('b', 30, 'lorem');
我可以查询
SELECT *
FROM pages
WHERE category_id not in (SELECT category_id FROM pages WHERE name = 'invalid' AND some_setting = 'true')
但是由于page[name=special]
不需要存在,我无法轻易将其转换为联接。有人有什么想法吗?这是一个指向SQLFiddle的链接,但它拒绝保存查询:http://sqlfiddle.com/#!15/c4ca7
答案 0 :(得分:1)
您可以尝试使用
select pg1.*
from pages pg1
left join pages pg2 on pg1.category_id = pg2.category_id
group by pg1.id
having
ARRAY['invalid', 'true']::text != ALL (ARRAY_AGG(array[pg2.name, pg2.some_setting]::text))
order by pg1.id
;
为什么不使用in
语句?我知道not in
不使用索引。但是也没有使用它。