2011-07-22 70 views
5

Tôi đang thay thế truy vấn SQL cũ chưa được xử lý bằng phiên bản mới, vì nó không bao gồm một số hàng cần có.So sánh hai truy vấn SQL lớn

Truy vấn mới chắc chắn bao gồm các hàng bị thiếu này, nhưng tôi muốn hoàn toàn chắc chắn rằng nó cũng bao gồm tất cả các hàng từ truy vấn ban đầu.

Hai truy vấn sử dụng các bảng hoàn toàn khác nhau. Mỗi truy vấn là ~ 14000 hàng.

Có truy vấn nào tôi có thể viết để kiểm tra xem QueryA có chứa bất kỳ hàng nào mà QueryB không có không?

+0

Bạn có thể cho chúng tôi biết cột Primary Key là gì không? Trường nào trong mỗi truy vấn là duy nhất cho mỗi hàng. –

+0

Xin lỗi. Cả hai truy vấn chỉ trả lại một trường. Rõ ràng nó có cùng tên trong cả hai. Trường này không chứa giá trị trùng lặp. – Urbycoz

Trả lời

9

Bạn có thể làm một cái gì đó như thế này.

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 

Bạn có thể có thể bao gồm tất cả các cột trong "trên khoản" hoặc bạn chỉ có thể bao gồm các cột bạn cần phải đảm bảo các hàng đều giống nhau, chẳng hạn như các khóa chính.

+0

Điều này thật hoàn hảo. Cảm ơn bạn! – Urbycoz

2

Giả sử rằng cả hai truy vấn trả về cột khóa chính từ cùng một bảng:

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

Xin lưu ý rằng parantheses có nghĩa rằng đây là những truy vấn con.

+0

Truy vấn phức tạp có thể không có một định danh duy nhất của trường trong tập hợp kết quả. – MatBailie

+0

Không có nghĩa là không đúng. –

+1

Bạn cũng cần phải so sánh cả hai hướng. Điều gì sẽ xảy ra nếu 'QueryB' có kết quả là' QueryA' không? Điều này sẽ không hiển thị ngoại lệ. – JNK

1
  1. Chọn kết quả từ truy vấn cũ vào bảng tạm thời.
  2. Chọn kết quả từ truy vấn mới vào bảng tạm thời khác.
  3. Tham gia bên ngoài từ bảng này sang bảng khác, tương đương với tất cả các cột.
  4. Thêm mệnh đề where để chỉ trả về các hàng có các giá trị rỗng ở một bên hoặc bên kia.

Ví dụ, nếu kết quả trông giống như (theo lý thuyết):

UserId | FirstName | LastName | Email 

Sau đó chạy mỗi truy vấn vào một bảng tạm thời riêng biệt với cấu trúc tương tự, nói #resOld và '#resNew'.

Sau đó:

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. 

Truy vấn này sẽ chỉ trả lại hàng khi có hàng từ một kết quả thiết lập mà không phù hợp với các hàng trong khác.

EDIT: Đó là phức tạp hơn nó cần phải được, bạn chỉ có thể đảo ngược tiêu chí tham gia và loại bỏ WHERE như vậy:

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

Bạn có thể sử dụng LEFT OUTER JOIN không?

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

Nếu bạn có thể làm cho nó vào SQL Server, bạn chỉ có thể làm:

<Query 1> 
EXCEPT 
<Query 2> 

<Query 2> 
EXCEPT 
<Query 1> 

này sẽ chỉ ra hồ sơ mà không tồn tại trong các truy vấn khác. Nó kiểm tra tất cả các trường trong tập kết quả.

Tôi đã bao gồm cả hai hướng vì nếu có nhiều bản ghi ở phần dưới của tuyên bố EXCEPT, những thứ đó không được hiển thị dưới dạng ngoại lệ.

Các vấn đề liên quan