2016-08-19 16 views
0

通常、サブクエリをジョインに変換するのは比較的簡単ですが、このケースは私を悩ませています。`not in`サブクエリを` join`に変換する

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'); 

を考えると私はpage[name=special]は私が簡単に参加するために、これを変換することはできません存在する必要はないという事実に

SELECT * 
FROM pages 
WHERE category_id not in (SELECT category_id FROM pages WHERE name = 'invalid' AND some_setting = 'true') 

のためではなく、原因で問い合わせることができます。誰も考えられない?ここでSQLFiddleへのリンクですが、それはクエリを保存することを拒否:http://sqlfiddle.com/#!15/c4ca7

答えて

1

あなたがin文を何を使用していないのはなぜあなたが

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 
; 

を有する本を試すことができますか?私はnot inインデックスを使用していないことを知っています。しかし、それも使用していない。

+0

パフォーマンスが実際に私がより簡単な結合に切り替えることを望んでいた理由は...あなたが書いた構成を見て、実際には可能ではないことを恐れています。データベースをリファクタリングして、常に無効なレコードがあることを確認する必要があります。 :(ありがとう! – user6733568

関連する問題