2011-09-13 49 views
9

Tôi đang cố gắng chọn các mục từ bảng kết hợp có thỏa mãn hai hoặc nhiều giá trị của cùng một trường, âm thanh khó hiểu, để tôi giải thích.MySQL Chọn ID xuất hiện trên các hàng khác nhau với nhiều giá trị cụ thể cho một cột

+-----------------------+ 
| item_id | category_id | 
+-----------------------+ 
| 1  | 200  | 
| 1  | 201  | 
| 1  | 202  | 
| 2  | 201  | 
| 2  | 202  | 
| 3  | 202  | 
| 3  | 203  | 
| 4  | 201  | 
| 4  | 207  | 
+-----------------------+ 

Trong bảng, tôi muốn chỉ có thể chọn các mục thuộc danh mục tôi vượt qua. Vì vậy, ví dụ, nếu tôi vượt qua ID danh mục 201 và 202, tôi chỉ muốn các mục có trong cả hai danh mục (chúng có thể có các danh mục khác nhưng cần phải có ít nhất các danh mục tôi đang truy vấn), vì vậy trong trường hợp này, tôi muốn mục 1 và 2 chỉ vì họ là những người duy nhất có trong loại 201 và 202.

câu lệnh SQL ban đầu của tôi là một cái gì đó giống như

SELECT * FROM item_category WHERE category_id = 201 AND category_id = 202; 

Nhưng rõ ràng rằng sẽ không làm việc.

SELECT * FROM item_category WHERE category_id = 201 OR category_id = 202; 

Truy vấn trên cũng sẽ không hoạt động vì nó cũng sẽ trả về các mục 4 và 3.

Vậy làm cách nào để tôi chỉ chọn các mục phải có ít nhất trong cả hai danh mục?

Hãy nhớ rằng tôi có thể chuyển nhiều hơn 2 ID danh mục.

Cảm ơn sự giúp đỡ của bạn.

Trả lời

8

Biểu thức của bạn trong mệnh đề WHERE hoạt động dựa trên hàng đơn của tập hợp kết quả đã tham gia. Đó là lý do tại sao WHERE category_id = 201 AND category_id = 202 không hoạt động - bởi vì nó không thể là hai giá trị trên một hàng.

Vì vậy, bạn cần một số cách để nối hai hàng từ bảng vào một hàng của tập hợp kết quả. Bạn có thể làm điều này với một tự tham gia:

SELECT c1.item_id 
FROM item_category AS c1 
INNER JOIN item_category AS c2 ON c1.item_id = c2.item_id 
WHERE c1.category_id = 201 AND c2.category_id = 202 

Kỹ thuật này khó có thể mở rộng lên khi bạn muốn tìm kiếm ba, bốn, năm hoặc nhiều giá trị, bởi vì nó đòi hỏi N-1 tham gia để đối sánh các giá trị N.

Vì vậy, phương pháp khác là sử dụng GROUP BY:

SELECT c.item_id, COUNT(*) AS cat_count 
FROM item_category AS c 
WHERE c.category_id IN (201,202) 
GROUP BY c.item_id 
HAVING cat_count = 2 

Cả hai kỹ thuật là không sao, và làm việc tốt hơn trong những hoàn cảnh khác nhau.

+0

Cảm ơn bạn, truy vấn thứ hai có vẻ phù hợp hơn trong trường hợp này và có vẻ hoạt động tốt! Cảm ơn một lần nữa! – flicker

-2

Bạn có thể thử:

SELECT * FROM item_category WHERE category_id IN (201, 202, ...)

(hoặc, như những ý kiến ​​nói ... bạn có thể không.)

+0

Điều đó sẽ trả về item_ids 3 và 4 – Bruce

0

Sử dụng cả JOIN, hoặc một GROUP BY:

SELECT category_id, fieldhere, anotherfield 
FROM item_category 
WHERE category_id in (201,202) 
GROUP BY category_id 
HAVING count(category_id) = 2 
0

Giả sử mỗi mục_id, category_id là duy nhất,

select *, count(item_id) as c from item_category 
where category_id in (201, 202) 
group by item_id 
having c = 2; 

Thay thế c = 2 bằng c = (số danh mục)

0

Tôi không có thời gian để cung cấp các truy vấn chính xác ngay bây giờ, nhưng thử một cái gì đó như thế này:

select item_category.* from 
item_category , item_category ic1, item_category ic2 where 
ic1.category_id = 201 and 
ic2.category_id = 202 and 
ic1.item_id = ic2.item_id and 
item_category.item_id = ic1.item_id and 
item_category.item_id = ic2.item_id; 

Có lẽ điều kiện là sai nhưng bạn có thể thử một cái gì đó theo cách này.

+0

Tôi không chắc chắn nếu ic1.item_id = ic2.item_id thực sự là cần thiết. – martincho

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