2010-11-16 117 views
1

兩個表:
a)用列svn3name revno compname
b)中archdetails與列name version compname inFlat爲什麼這兩個sql查詢的輸出不同?

不應該這2個查詢輸出相同的結果。查詢2的輸出是正確的。 query1有什麼問題?

QUERY1:
select sum(CASE WHEN inFlat=1 THEN 1 ELSE 0 END) from archdetails inner join svn3 on archdetails.compname=svn3.compname where archdetails.name='ant' AND version='1.4' AND (revno='r274642' OR revno='r274578' OR revno='r274533')

QUERY2:
select sum(CASE WHEN inFlat=1 THEN 1 ELSE 0 END) from archdetails where name='ant' AND version='1.4' AND compname IN (select compname from svn3 where revno ='r274642' OR revno='r274578' OR revno='r274533')

回答

2

如果svn3有不止一個行具有相同的compname也有要求revno值之一,然後查詢1會再計算每個svn3行。查詢2只會計算每個compname一次。 IN子句將消除第二個查詢中的任何重複compname條目。

如果您不想計算重複的compname條目,那麼您需要將它們歸入子查詢中。一種方法是使用IN子句,就像在查詢2中一樣。另一種方法是在子查詢上使用GROUP BY,並將該子查詢命名爲。然後將指定的子查詢加入archdetails表。

如果您試圖解決性能問題,那麼我會建議將主鍵和外鍵添加到表中。我認爲這會加快速度。

我見過一些意見,EXISTS有時比IN更快,但我還沒有看到任何證據支持這一點。你可能想試驗一下。

+0

是的,你是對的。我如何修改查詢1呢?即使在索引之後,使用查詢2的速度太慢 – Gaurav 2010-11-16 18:20:23

+2

您是否嘗試使用query2,但是使用'exists'語句而不是'in'條件?在性能方面通常要好得多。 – 2010-11-16 18:58:43

+0

謝謝,會嘗試使用EXISTS。 – Gaurav 2010-11-16 21:21:40

0

在看到其他的答案,我現在覺得這是不太可能的解釋,但將在情況不是圍繞保持它...

我的猜測是,這是由NULL值引起的(歸咎於NULL是通常有效的策略)。 archdetails.compnamesvn3.compname是否可以爲空,如果是這樣,那麼這些列中的任何一個表是否包含空值?如果存在空值,則需要確定比較空值時的確切情況。

如果是由空值引起的,那麼您的ANSI_NULLS設置也可能在這裏起作用。

+0

對不起,這裏沒有NULL值。 – Gaurav 2010-11-16 18:19:28

2

不,這兩個查詢是不一樣的 - 第一個查詢加入到compname上的svn3記錄,1.4版本和3個revno值中的一個。如果一個給定的compname(版本'1.4'和3個revno值中的任何一個)存在多個svn3記錄,那麼query1將返回更多的結果。

可能的解決方案:變化

sum(CASE WHEN inFlat=1 THEN 1 ELSE 0 END)

count(distinct CASE WHEN inFlat=1 THEN archdetails.compname END)

(假設archdetails.compname唯一標識在該查詢要被計數的每個archdetails記錄,鑑於其內的其它約束。)

+0

我想這就是發生了什麼。任何方式來糾正這使用其他形式的聯接或修改? – Gaurav 2010-11-16 18:18:49

+0

@Gaurav:查看編輯答案。 – 2010-11-16 18:33:00

+0

謝謝,應檢查並讓你知道結果。 – Gaurav 2010-11-16 18:36:50

相關問題