我正在使用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