2010-01-23 94 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