2011-07-22 44 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声明的较低部分有更多记录,则这些记录不会显示为例外。