2016-08-19 55 views
0

通常將子查詢轉換爲連接相對簡單,但這種情況一直困擾着我。鑑於將`不在'子查詢轉換爲`加入'

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

回答

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沒有使用索引。但還沒有使用它。

+0

表現的確是我希望切換到更簡單的連接的原因......看着你剛剛寫下的構造,我擔心它實際上是不可能的。猜猜我需要重構我的數據庫,並確保始終有一個「無效」記錄。 :( 謝謝! – user6733568