2011-01-20 27 views
12

Tôi có một danh sách các mục trên một trang web. Mỗi mục có một số danh mục gắn liền với nó, hãy gọi các thể loại phim thể loại này. Trong tìm kiếm nâng cao, tôi cho phép mọi người chọn hộp cho các thể loại mà họ thích và nó sẽ phát ra danh sách phim phù hợp với bất kỳ thể loại nào được chọn.Sử dụng mệnh đề MySQL IN là bao gồm tất cả (VÀ thay vì HOẶC)

Tôi có một câu hỏi như thế này:

AND column IN ('5', '8', '9') 

Vấn đề ở đây là nếu bạn chọn "hoạt hình" và "kinh dị" bạn sẽ nhận được một loạt các phim hoạt hình Disney ("hoạt hình") và series SAW ("kinh dị").

Tôi muốn điều chỉnh tìm kiếm thành bao gồm tất cả, vì vậy nó sẽ chỉ trả lại kết quả phù hợp với TẤT CẢ các thể loại được chọn, vì vậy các mục được đánh dấu là 'hoạt ảnh' và 'kinh dị' sẽ được trả lại.

Cặp item_id và category_id được lưu trữ trong một bảng riêng biệt. Vì vậy, đối với một bộ phim có ID 55, có thể có 4 thể loại, do đó sẽ có 4 hàng có item_id = 55 và category_id bằng 4 Id danh mục.

+2

Không, cột chỉ chứa 1 giá trị. Làm thế nào có thể 1 bằng 1, 2 và 3 cùng một lúc? – Kleinux

+3

Bạn có thể giải thích tình trạng này có thể đúng không ?! '(cột = 5 VÀ cột = 8 VÀ cột = 9)' – RichardTheKiwi

+0

@ kleinux Tôi giả sử đó là những ví dụ và thực sự sẽ là các tham số có thể được tạo ra bởi ứng dụng. – jzd

Trả lời

17

EDIT: Đã sửa đổi câu trả lời của tôi để phù hợp hơn với câu hỏi được chỉnh sửa của OP.

select i.MovieName 
    from item i 
     inner join ItemCategory ic 
      on i.item_id = ic.item_id 
    where i.item_id = 55 
     and ic.category_id in ('5','8','9') 
    group by i.MovieName 
    having count(distinct ic.category_id) = 3 
+1

Tôi nghĩ rằng đây là những gì OP là sau, quay trở lại phim có tất cả các loại và không chỉ một trong số họ .... – Leslie

+0

Khó quy mô này tức là yêu cầu SQL động (yuk!:) – onedaywhen

+0

Điều này sẽ hoạt động, tuy nhiên có hơn 3 triệu lượt tìm kiếm mỗi ngày trên một DB khá lớn. Hầu hết được lưu trữ, nhưng đây sẽ là một truy vấn nặng. –

-2

Nếu danh sách giá trị có nhiều giá trị, thì bạn có thể tối ưu hóa nó một cách dễ dàng. Ví dụ này:

AND (column = 5 AND column = 8 AND column = 9) 

trở thành:

AND (column = 5 AND 5 = 8 AND 8 = 9) 

(kể từ khi mối quan hệ của là như nhau là transitive). Có thể được tối ưu hóa thêm như sau:

AND false 

cho kết quả tương tự như truy vấn bạn hỏi - và thực sự, thực sự nhanh trên hầu hết các cơ sở dữ liệu.

Nghiêm túc, bạn có thể thuật lại câu hỏi này không?

+0

Tôi nghĩ rằng OP chỉ muốn hiển thị phim có cả ba tùy chọn được chọn – Leslie

+0

, sau khi chỉnh sửa câu hỏi có ý nghĩa. Quay lại khi tôi viết câu trả lời tôi tin rằng nó không. – fdreger

1

Nếu bạn đang sử dụng adhoc truy vấn bạn có thể xây dựng một cái gì đó như thế này

select * 
from item_id t0 
left join category_id t1 on t1.itemId=t0.Id and t1.gemres = 5 
left join category_id t2 on t2.itemId=t0.Id and t2.gemres = 8 
left join category_id t3 on t3.itemId=t0.Id and t3.gemres = 9 
where (t1.Id is not null and t2.Id is not null and t3.Id is not null) 
+0

Số lượng đối số là 3 chỉ dành cho mục đích ví dụ. Nó có thể nằm trong khoảng từ 1 đến hơn 10. –

+0

Đó là lý do tại sao tôi đã viết điều này sẽ hoạt động nếu bạn đang sử dụng truy vấn adhoc. Kỳ vọng là bạn sẽ xây dựng truy vấn động. – Kleinux

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