我正在使用sqlite3,但它的SQL支持是相當標準的,所以只要SQL不包含任何專有擴展,所有應該都是好的。我的架構如下:查詢優化,擺脫子查詢
create table test (
_id integer primary key,
name text,
enabled integer not null default 1
);
create table task (
_id integer primary key,
_test_id integer not null references test on delete cascade,
favorite integer not null default 0,
comment text
);
簡而言之:有可以啓用或不測試;測試有多個任務,可以是最喜歡的,並且可以有評論。
兩個最複雜的查詢,我需要編寫如下:
一個選擇它檢索信息的數據庫是否包含至少1喜愛和至少1評論任務對於任何測試啓用(即唐試驗組)。我想出了以下的怪物:
select exists(select task._id from task as task inner join test as test on task._test_id=test._id where task.favorite=1 and test.enabled=1 limit 1) as has_favorite, exists(select task._id from task as task inner join test as test on task._test_id=test._id where task.comment is not null and test.enabled=1 limit 1) as has_commented;
一個選擇符合有關其任務計數信息一起取回試驗覈心數據(ID,姓名等),測試是否包含至少1喜愛和至少1評論任務。我想出了這個:
select test.*, (select count(*) from task where _test_id=test._id) as task_count, exists(select _id from task where favorite=1 and _test_id=test._id limit 1) as has_favorite, exists(select _id from task where comment is not null and _test_id=test._id limit 1) as has_commented from test as test where test.enabled=1 order by test._id asc
其實,「has_favorite」和「has_commented」信息不是唯一的,但他們描繪了我的懷疑 - 這些查詢都是相當大的,含有相當數量的子查詢(我讀取子查詢對性能不利)和重複。
問題:是否可以更容易地編寫查詢?讓他們更好,更簡潔?不是很重複?例如,我想也許有辦法只執行任務和測試表之間的一個連接,並以某種方式從那裏派生數據。
編輯:所以看來我可以這樣寫的第一個:
select
count(*) as task_count,
max(task.favorite) as has_favorite,
count(task.comment) as has_commented
from task as task inner join test as test on task._test_id=test._id where test.enabled=1;
這對於第二個:
select
test.*,
count(*) as task_count,
max(task.favorite) as has_favorite,
count(task.comment) as has_commented
from task as task inner join test as test on task._test_id=test._id where test.enabled=1 group by test._id;
如果MAX(task.favorite)是什麼> 0表示至少有1個任務是最喜歡的。我可以用'sum(task.favorite)'代替它,如果總和> 0,那麼有一個最喜歡的。
這是否比原來的建議好(存在(子選擇))?這似乎更容易。
是否有版本3.8.3或更高版本(它具有公用表表達式)? – 2015-02-09 22:03:08
我應該在3.8.4.3(Android Lollipop,5.0)上運行,但我可能必須早於3.7.4(Android 4.0)兼容。不過,我會好奇的,你會採取什麼。 – wujek 2015-02-09 22:13:03
[WITH子句](http://www.sqlite.org/lang_with.html)。你可以創建一個視圖。 – 2015-02-10 07:47:46