2010-01-23 92 views
1

我有一个SQL查询:这个SQL查询可以被简化吗?

select * from contactmeta 
WHERE 
contactmeta.contact_id in 
(
select tob.object_id from tagobject tob, tag t, taggroup tg 
where tob.tag_id = t.tag_id 
and t.tag_group_id = tg.tag_group_id 
and tob.object_type_id = 14 
and tg.org_id = contactmeta.group_id 
and (t.name like '%campaign%') 
) 
AND 
contactmeta.contact_id in 
(
select tob.object_id from tagobject tob, tag t, taggroup tg 
where tob.tag_id = t.tag_id 
and t.tag_group_id = tg.tag_group_id 
and tob.object_type_id = 14 
and tg.org_id = contactmeta.group_id 
and (t.name like '%bounced%') 
) 

我的问题是,我需要简化WHERE子句内的查询的部分(我不能让与contactmeta表等其他连接)。这是因为WHERE子句是在静态SQL上动态创建的。

您可以看到,除了t.name条件,where条件几乎相同。

感谢您的时间

SK

+0

。在你的子查询另一个不同之处。第一个有t.tag_group_id = tg.tag_group_id,第二个没有。 – rayd09 2010-01-23 16:52:03

+0

@ rayd09:我认为这只是复制和粘贴错误,因为第二个子查询有两次'tob.tag_id = t.tag_id'。 @Samuel:这是真的吗?或者你的问题中的查询是否正确? – 2010-01-23 16:58:15

+0

是的,这是一个剪切和粘贴错误...对不起...这个让我看看我是否可以编辑它。 – Samuel 2010-01-23 17:06:55

回答

2

这是不是真的任何简单(在代码方面),但将是更好的性能,因为你正在使用联接,而不是IN操作:

select contactmeta .* from contactmeta 

inner join tagobject tob, tag t, taggroup tg 
on tob.tag_id = t.tag_id 
and t.tag_group_id = tg.tag_group_id 
and tob.object_type_id = 14 
and tg.org_id = contactmeta.group_id 
and (t.name like '%campaign%') 

inner join tagobject tob2, tag t2, taggroup tg2 
on tob2.tag_id = t2.tag_id 
and t2.tag_group_id = tg2.tag_group_id 
and tob2.object_type_id = 14 
and tg2.org_id = contactmeta.group_id 
and (t2.name like '%bounced%') 

编辑:如果这是不可能的(由于您的意见约JOIN限制),那么你可以逻辑的抽象部分成如意见

create view myView 
as 
select * from tagobject tob, tag t, taggroup tg 
    on tob.tag_id = t.tag_id 
    and t.tag_group_id = tg.tag_group_id 

然后在原始sql中使用该视图。

+0

@davek:OP写道他们不能改变查询结构,但需要WHERE子句的解决方案。 – 2010-01-23 17:05:09

+0

这里第一个解决方案的一个可能的问题是,虽然OP的当前查询只会从contactmeta返回一个条目,但如果两个内部连接返回不同数量的记录,则可能会有多个结果。 – MartW 2010-01-23 17:08:30

+0

好了更正了现在的查询 – Samuel 2010-01-23 17:14:06

0

试试这个:

select * from contactmeta 
WHERE 
contactmeta.contact_id in 
(
select tob.object_id from tagobject tob, tag t, taggroup tg 
where tob.tag_id = t.tag_id 
and tob.object_type_id = 14 
and tg.org_id = contactmeta.group_id 
and (
    (t.tag_group_id = tg.tag_group_id and t.name like '%campaign%') 
    or 
    (tob.tag_id = t.tag_id and t.name like '%bounced%') 
) 
) 
+1

我不认为这是一样的,尽管起初我以为是一样的。 OP的查询匹配至少有一行含有“广告系列”**的行,以及**至少有一行含有“反弹”的行。您的查询已经匹配具有** **“广告系列”**或**“反弹”(或两者)的行,但不需要**两者。 – 2010-01-23 17:02:23

+0

不完全正确。由于2个名称的AND条件,他的查询必须加入与(tag/tagobject/taggroup)的联系人两次。 – rayd09 2010-01-23 17:05:03

+0

Bandi-T说的话对我来说很合适。 – rayd09 2010-01-23 17:06:46

2

如前所述,子查询在WHERE子句是不一样的。

我不确定你的意思是“简化”,简化为什么?不详细?较简单的查询计划?更多的性能?换句话说,你想解决什么问题?

一些想法:

  • 您可以为您的 子选择视图(或子查询,如果两者之间的差异 是 目的),这将减少 冗长外。

  • 获取查询和 看表扫描的查询计划。

  • 考虑使用全文索引 ,而不是像一个外卡在 模式的开始,因为这 需要整个指数是 扫描(假设在列的索引 ) - 如果没有 索引然后添加一个。

+0

之外,所有内容都是相同的。我更正了查询。通过简化我的意思是减少重复... – Samuel 2010-01-23 17:12:57

+0

查看创意很棒!指数的想法也不错。 – Samuel 2010-01-23 17:22:02