2013-04-12 36 views
20

Giả sử tôi có hai bảng:Chọn hàng phù hợp tất cả các mục trong một danh sách

cars - danh sách các xe

carname | modelnumber | ... 

passedtest - chứa tất cả các bài kiểm tra đó một chiếc xe thông qua:

id | carname | testtype | date | ... 
1 | carA | A  | 2000 | 
2 | carB | C  | 2000 | 
3 | carC | D  | 2001 | 
4 | carA | C  | 2002 | 

Bây giờ, làm cách nào tôi có thể chọn một chiếc xe từ bảng passedtest đã vượt qua tất cả các thử nghiệm (A, B, C, D)?

Tôi đã thử tuyên bố IN nhưng nó cũng khớp với những chiếc ô tô vượt qua cả một thử nghiệm. Tôi đang tìm kiếm một tuyên bố để khớp với tất cả các giá trị trong danh sách trên tất cả các hàng.

Trả lời

29

Làm thế nào về điều này?

SELECT carname 
FROM PassedTest 
GROUP BY carname 
HAVING COUNT(DISTINCT testtype) = 4 

Bạn cũng có thể sử dụng nó như một tuyên bố bên trong dành thông tin từ bảng cars:

SELECT * 
FROM cars 
WHERE carname IN (
    SELECT carname 
    FROM PassedTest 
    GROUP BY carname 
    HAVING COUNT(DISTINCT testtype) = 4 
) 
+0

nhờ nhưng sản lượng tôi có được lặp lại tôi nghĩ rằng vì để tạo ra chiếc xe bảng tôi được sử dụng bên trong tham gia – user1229351

+0

Tuy nhiên, điều này sẽ không làm việc với ký tự đại diện, vì trong trường hợp này, rõ ràng không thể đếm được thành lập. –

20

Đây là loại vấn đề được gọi là Relational Division.

SELECT a.* 
FROM Cars a 
     INNER JOIN 
     (
      SELECT CarName 
      FROM PassedTest 
      WHERE testType IN ('A', 'B', 'C', 'D') 
      GROUP BY CarName 
      HAVING COUNT(*) = 4 
     ) b ON a.CarName = b.CarName 

nếu một hạn chế UNIQUE không được thực thi trên TestType cho mỗi CarName trên bàn PassedTest một từ khóa DISTINCT được yêu cầu trên COUNT() vì vậy nó sẽ chỉ đếm giá trị duy nhất.

SELECT a.* 
FROM Cars a 
     INNER JOIN 
     (
      SELECT CarName 
      FROM PassedTest 
      WHERE testType IN ('A', 'B', 'C', 'D') 
      GROUP BY CarName 
      HAVING COUNT(DISTINCT TestType) = 4 
     ) b ON a.CarName = b.CarName 

nhưng nếu bạn chỉ quan tâm trên CARNAME sau đó bạn không cần phải tham gia các bảng. Truy vấn trên bảng PassedTest sẽ phù hợp với nhu cầu của bạn.

SELECT CarName 
FROM PassedTest 
WHERE testType IN ('A', 'B', 'C', 'D') 
GROUP BY CarName 
HAVING COUNT(*) = 4 
0

Bạn muốn thực hiện phân chia quan hệ, một thao tác không được triển khai trong SQL. Dưới đây là một ví dụ trong đó chúng ta có một sản phẩm cung cấp bảng và một bắt buộc về sản phẩm bảng:

CREATE TABLE product_supplier (
    product_id int NOT NULL, 
    supplier_id int NOT NULL, 
    UNIQUE (product_id, supplier_id) 
); 
INSERT INTO product_supplier (product_id, supplier_id) VALUES 
(1, 1), 
(2, 1), 
(3, 1), 
(1, 2), 
(2, 2), 
(3, 2), 
(4, 2), 
(2, 3), 
(3, 3), 
(4, 3); 

CREATE TABLE reqd (
    product_id int NOT NULL, 
    UNIQUE (product_id) 
); 
INSERT INTO reqd (product_id) VALUES 
(1), 
(2), 
(3); 

... và chúng tôi muốn tìm tất cả các nhà cung cấp mà cung cấp tất cả các sản phẩm theo yêu cầu và có lẽ những người khác. Kết quả trong ví dụ trên sẽ là nhà cung cấp 1 và 2.

Giải pháp thẳng nhất về phía trước là thế này:

SELECT product_supplier.supplier_id 
FROM product_supplier 
LEFT JOIN reqd ON product_supplier.product_id = reqd.product_id 
GROUP BY product_supplier.supplier_id 
HAVING COUNT(reqd.product_id) = (SELECT COUNT(*) FROM reqd); 
+-------------+ 
| supplier_id | 
+-------------+ 
|   1 | 
|   2 | 
+-------------+ 

Và nếu chúng ta muốn tìm tất cả các nhà cung cấp mà cung cấp tất cả các sản phẩm cần thiết và không có những người khác (chính xác bộ phận/no còn lại) sau đó thêm một điều kiện nữa các phần trên:

SELECT product_supplier.supplier_id 
FROM product_supplier 
LEFT JOIN reqd ON product_supplier.product_id = reqd.product_id 
GROUP BY product_supplier.supplier_id 
HAVING COUNT(reqd.product_id) = (SELECT COUNT(*) FROM reqd) 
AND COUNT(product_supplier.product_id) = (SELECT COUNT(*) FROM reqd); 
+-------------+ 
| supplier_id | 
+-------------+ 
|   1 | 
+-------------+ 

Một giải pháp thay thế là để diễn đạt lại vấn đề: chọn s uppliers nơi sản phẩm được yêu cầu không tồn tại mà không tồn tại trong các sản phẩm do nhà cung cấp cung cấp. Hmmm:

SELECT DISTINCT supplier_id 
FROM product_supplier AS ps1 
WHERE NOT EXISTS (
    SELECT * 
    FROM reqd 
    WHERE NOT EXISTS (
     SELECT * 
     FROM product_supplier AS ps2 
     WHERE ps1.supplier_id = ps2.supplier_id AND ps2.product_id = reqd.product_id 
    ) 
); 
+-------------+ 
| supplier_id | 
+-------------+ 
|   1 | 
|   2 | 
+-------------+ 
Các vấn đề liên quan