2012-09-24 37 views
15

Làm cách nào để chỉ chọn một mục mà bạn muốn trong danh sách IN? ví dụ:Cách chọn mục khớp Chỉ danh sách IN trong máy chủ sql

select * from pagetags where TagID in (1,2,4) 

Bây giờ tôi muốn tất cả các trang có tất cả 3 ID được gán cho họ (1,2,4), không chỉ bất kỳ trang nào trong số đó nhưng tất cả?

Có cách nào không? bất kỳ nhà điều hành nào khác? Tôi đã thử = Any= All nhưng không có may mắn.

Trả lời

22

Thuật ngữ cho loại sự cố này là relational division. Một cách dưới đây.

SELECT PageID 
FROM pagetags 
WHERE TagID IN (1, 2, 4) 
GROUP BY PageID 
HAVING Count(DISTINCT TagID) = 3 
+0

ok, tôi cần phải viết lược đồ ban đầu của mình vì nó khó hơn ví dụ trên :) nhưng bạn đã lưu tôi ở đó, cảm ơn một tấn. – Ali

0

bạn có thể thử một cái gì đó như thế này:

SELECT id, Tag FROM (
SELECT id, Tag, COUNT(*) OVER(partition by id) as cnt 
FROM pagetags 
WHERE Tag in(1,2,4) 
GROUP BY id, tag 
) a WHERE a.cnt = 3 
0

Câu trả lời được lựa chọn từ Martin Smith

SELECT PageID 
FROM pagetags 
WHERE TagID IN (1, 2, 4) 
GROUP BY PageID 
HAVING Count(DISTINCT TagID) = 3 

là đúng nhưng nếu tốc độ là một vấn đề sau đó thử này.

Tôi có một bảng lớn làm điều tương tự và có hiệu suất tốt hơn 10x với những điều sau đây.
0,2 giây so với 2,0 giây đối với truy vấn trả về 272 từ bảng có 3 triệu hàng.
Cũng được thử nghiệm trên một bảng lớn hơn với 5 thẻ và cùng một 10x nhưng bây giờ 0,5 so với 5,0.
Chỉ mục là PageID, TagID với hàng triệu PageID và hàng trăm TagID.
Kịch bản chung nơi nhiều đối tượng được gắn thẻ thuộc tính đa giá trị.

SELECT distinct(p1.PageID) 
    FROM pagetags p1 
    JOIN pagetags p2 
     ON p2.PageID = p1.PageID 
     AND p2.TagID = 2 
    JOIN pagetags p3 
     ON p3.PageID = p1.PageID 
     AND p3.TagID = 4 
    WHERE p1.PageID = 1 
ORDER BY p1.PageID 

hoặc

SELECT distinct(PageID) 
    FROM pagetags 
    WHERE TagID = 1 
    INTERSECT 
    SELECT distinct(PageID) 
    FROM pagetags 
    WHERE TagID = 2 
    INTERSECT 
    SELECT distinct(PageID) 
    FROM pagetags 
    WHERE TagID = 4 
ORDER BY PageID 

thích cuối cùng như với hơn 5 gia nhập truy vấn tối ưu thường sẽ làm cho một số quyết định sai lầm.
Và với điều này đã không được sử dụng hết Group Bởi nếu bạn cần nó cho một tập hợp.

+0

Nó phụ thuộc vào các chỉ mục có sẵn và số lượng thẻ trong hệ thống. Về cơ bản giống như so sánh ['PIVOT' so với' JOIN'] (http://stackoverflow.com/questions/7448453/sql-server-pivot-vs-multiple-join/7449213#7449213). Nếu số lượng thẻ để xem xét là biến này không phải là rất mở rộng ngoại trừ nếu truy vấn được tạo ra thông qua SQL động. –

+0

@MartinSmith Trong trường hợp của tôi, chỉ mục là PageID TagID. Ít hơn 1000 ID nhưng có thể có hàng triệu PageID. Được sử dụng bởi một chương trình. Vì vậy, tôi sẵn sàng lấy hiệu suất 10x. – Paparazzi

0
SELECT distinct(PageID) 
FROM pagetags 
WHERE TagID IN (1,2,4) 
and PageID in 
(select distinct(PageID) from pagetags group by PageID having count(TagID)=3) 
group by PageID 
+3

Một số lời giải thích có thể hữu ích! –

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