2010-10-12 24 views
5

Hiện nay đang gặp khó khăn với việc tìm kiếm một cách để xác nhận 2 bàn (hiệu quả rất nhiều hàng cho Bảng A)SQL Query - Đảm bảo hàng tồn tại cho mỗi giá trị trong()

Tôi có hai bảng

Bảng A

ID 
A 
B 
C 

Bảng phù hợp

ID Number 
A 1 
A 2 
A 9 
B 1 
B 9 
C 2 

Tôi đang cố gắng viết truy vấn SQL Server về cơ bản kiểm tra để đảm bảo mọi giá trị trong Bảng A tồn tại một hàng cho một tập giá trị biến (1, 2,9)

Ví dụ bên trên là không chính xác vì t phải có cho mỗi bản ghi trong A một bản ghi tương ứng trong Bảng phù hợp với mỗi giá trị (1,2,9). Mục tiêu cuối cùng là:

Bảng phù hợp

ID Number 
A 1 
A 2 
A 9 
B 1 
B 2 
B 9 
C 1 
C 2 
C 9 

Tôi biết khó hiểu của nó, nhưng nhìn chung cho mỗi X trong (một số quy định) nên có một kỷ lục tương ứng trong bảng phù hợp. Tôi rõ ràng đã đơn giản hóa mọi thứ.

Vui lòng cho tôi biết nếu bạn cần làm rõ.

+0

Luôn có ba giá trị? Giá trị luôn là 1,2 và 9? – Kuberchaun

+1

Không có 17 giá trị thực sự .. và chúng không phải tuần tự. (1,3,4,5 7, vv) – Nix

Trả lời

10

Sử dụng:

SELECT a.id 
    FROM TABLE_A a 
    JOIN TABLE_B b ON b.id = a.id 
    WHERE b.number IN (1, 2, 9) 
GROUP BY a.id 
    HAVING COUNT(DISTINCT b.number) = 3 

Các DISTINCT trong COUNT đảm bảo rằng các bản sao (IE: A có hai bản ghi trong table_b với giá trị "2") khỏi bị sai coi là một kỷ lục chính xác. Nó có thể được bỏ qua nếu cột number có một ràng buộc khóa duy nhất hoặc chính trên đó.

Các HAVING COUNT(...)phải bằng với số các giá trị quy định trong mệnh đề IN.

+0

Tôi nghĩ rằng điều này sẽ làm việc, ngu ngốc đơn giản (bực bội). Thử nghiệm ngay bây giờ. Cảm ơn. – Nix

+0

@Nix: Tôi cho rằng tôi có thể làm cho nó phức tạp hơn? :) –

+0

+1: có vẻ tốt ... – RedFilter

0

Tạo bảng giá trị tạm thời bạn muốn. Bạn có thể làm điều này động nếu các giá trị 1, 2 và 9 nằm trong một số bảng mà bạn có thể truy vấn.

Sau đó, SELECT FROM tempTable WHERE NOT IN (SELECT * FROM TableMatched)

+0

Tôi cần đảm bảo cho mỗi hàng tất cả các giá trị trong IN tồn tại trong bảng so khớp. Không chỉ nói với tôi nếu tôi có giá trị không có trong đó? – Nix

+0

Bạn muốn điều gì xảy ra nếu thiếu hồ sơ? SELECT của tôi sẽ không trả về bất kỳ bản ghi nào nếu tất cả các bản ghi mong muốn tồn tại trong TableMatched. Điều đó sẽ vượt qua bài kiểm tra, đúng không? Nếu có hồ sơ được trả lại ở đây, thì kiểm tra không thành công. Bạn có muốn SQL này INSERT các bản ghi bị thiếu? – DOK

0

Tôi đã gặp tình huống này một lần. Giải pháp của tôi là như sau.

Ngoài TableA và TableMatched, có một bảng xác định các hàng sẽ tồn tại trong TableMatched cho mỗi hàng trong TableA. Hãy gọi nó là TableMatchedDomain.

Việc áp dụng sau đó truy cập TableMatched thông qua một điểm cho rằng kiểm soát hàng trả lại, như thế này:

create view TableMatchedView 
select a.ID, 
     d.Number, 
     m.OtherValues  
from TableA a 
     join TableMatchedDomain d 
     left join TableMatched m on m.ID = a.ID and m.Number = d.Number 

Bằng cách này, các hàng trả lại là luôn luôn đúng. Nếu có các hàng bị thiếu trong TableMatched, thì các số vẫn được trả về nhưng với các giá trị khác là null. Nếu có thêm giá trị trong TableMatched, thì chúng không được trả về, như thể chúng không tồn tại. Bằng cách thay đổi các hàng trong TableMatchedDomain, hành vi này có thể được kiểm soát rất dễ dàng. Nếu một giá trị đã được loại bỏ TableMatchedDomain, thì nó sẽ biến mất khỏi khung nhìn.Nếu nó được thêm trở lại một lần nữa trong tương lai, thì OtherValues ​​tương ứng sẽ xuất hiện lại như trước đây.

Lý do tôi thiết kế nó theo cách này là tôi cảm thấy rằng việc thiết lập một sự thiếu kiên nhẫn về cấu hình hàng trong TableMatched là quá giòn và thậm chí tệ hơn, được giới thiệu dự phòng. Vì vậy, tôi loại bỏ các hạn chế từ các nhóm hàng (trong TableMatched) và thay vào đó làm cho toàn bộ nội dung của một bảng khác (TableMatchedDomain) xác định hình thức chính xác của dữ liệu.

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