2011-07-22 163 views
5

我用新版本替換舊的不整齊的SQL查詢,因爲它沒有包含它應該有的幾行。比較兩個大的SQL查詢

新的查詢當然包含這些缺失的行,但我想完全確定它還包括原始查詢中的所有行。

這兩個查詢使用完全不同的表。每個查詢是~14000行。

是否有我可以編寫的查詢檢查QueryA是否包含QueryB沒有的任何行?

+0

你能告訴我們主鍵列是什麼嗎?每個查詢中的哪些字段對每一行都是唯一的。 –

+0

對不起。這兩個查詢只返回一個字段。很明顯,它們在兩者中都有相同的名稱。該字段不包含重複值。 – Urbycoz

回答

9

你可以做這樣的事情。

Select * FROM 
(
QUERY A GOES HERE 
) AS A 
LEFT JOIN 
(
QUERY B GOES HERE 
) AS B 
ON A.Col1=B.Col1 AND A.Col2=B.Col2 .... 
WHERE B.Col1 IS NULL 

您可以包括在「關於條款」中的所有列,也可以只包括你需要保證行是相同的,如主鍵列。

+0

這是完美的。謝謝! – Urbycoz

2

假設這兩個查詢返回同一個表的主鍵列:

select * 
from (QueryA) a 
where a.PK not in (select PK from (QueryB) b) 

請注意括號意味着,這些都是子查詢。

+0

複雜查詢在結果集中不太可能具有單個字段唯一標識符。 – MatBailie

+0

不太可能並不意味着這是真的。 –

+1

您還需要比較兩個方向。如果'QueryB'結果'QueryA'沒有結果呢?這不會顯示例外情況。 – JNK

1
  1. 將舊查詢結果選擇到臨時表中。
  2. 將新查詢的結果選擇到另一個臨時表中。
  3. 從一個表到另一個表的外連接,等同於所有的列。
  4. 添加where子句以僅返回一側或另一側有空值的行。

例如,如果結果看起來像(理論上):

UserId | FirstName | LastName | Email 

然後運行每個查詢成具有相同結構的單獨的臨時表,說#resOld和「#resNew」。

然後:

SELECT 
    * 

FROM #resOld OLD 

LEFT OUTER JOIN #redNew NEW -- LEFT OUTER JOIN, so we still retain rows which don't match 
    ON NEW.UserId = OLD.UserId 
    AND NEW.FirstName = OLD.FirstName 
    AND NEW.LastName = OLD.LastName 
    AND NEW.Email  = OLD.Email 

WHERE OLD.UserID IS NULL -- Only retain rows where we didn't match. Can use any field from OLD which cannot be null by design. 

當有來自設定一個結果不匹配其他行中的行這個查詢只能返回行。

編輯:也就是說複雜得多,它需要的,你可以顛倒連接標準和除去WHERE像這樣:

SELECT 
    * 

FROM #resOld OLD 

INNER JOIN #redNew NEW -- Inner join where rows are different. 
    ON NEW.UserId != OLD.UserId 
    AND NEW.FirstName != OLD.FirstName 
    AND NEW.LastName != OLD.LastName 
    AND NEW.Email  != OLD.Email 
1

你能用LEFT OUTER JOIN嗎?

SELECT 
    * 
FROM 
    (< put query 1 here >) AS Query1 
LEFT JOIN 
    (< put query 2 here >) AS Query2 
    ON Query1.Field1 = Query2.Field1 
    AND Query1.Field2 = Query2.Field2 
    AND Query1.Field3 = Query2.Field3 
    etc, etc 
WHERE 
    Query2.Field1 IS NULL 
1

如果你能得到它到SQL Server,你可以做:

<Query 1> 
EXCEPT 
<Query 2> 

<Query 2> 
EXCEPT 
<Query 1> 

這隻會說不會在其他查詢存在輸出記錄。它檢查結果集中的所有字段。

我包含兩個方向,因爲如果在EXCEPT聲明的較低部分有更多記錄,則這些記錄不會顯示爲例外。