OK, đây là nỗ lực của tôi. Có thể thực hiện logic này theo cách không yêu cầu 5 truy cập vào cùng một bảng, nhưng tôi không thể nghĩ ra nó ngay bây giờ.
Logic ở đây trước hết là loại bỏ các đối tượng trùng lặp, sau đó đếm số ID còn lại. Truy vấn con NOT IN
đại diện cho các đối tượng có đối tượng phù hợp với ID nhỏ hơn. Truy vấn con tham gia các tham số của hai đối tượng t1 và t2, sau đó đếm số lượng tham số phù hợp với mỗi cặp t1/t2. Nếu số tham số phù hợp giống với số tham số trong t1 và t2, thì t2 và t1 là các kết quả phù hợp và chúng ta nên loại trừ t1 khỏi resultset.
DECLARE @tab TABLE (ID int, parameter varchar(2));
INSERT INTO @tab
SELECT 1, 'A' UNION ALL
SELECT 1, 'B' UNION ALL
SELECT 2, 'A' UNION ALL
SELECT 3, 'A' UNION ALL
SELECT 3, 'B' UNION ALL
SELECT 4, 'A' UNION ALL
SELECT 5, 'C' UNION ALL
SELECT 5, 'D';
SELECT
COUNT(DISTINCT t.ID) AS num_groups
FROM
@tab AS t
WHERE
t.ID NOT IN
(SELECT
t1.ID AS ID1
FROM
@tab AS t1
INNER JOIN
@tab AS t2
ON
t1.ID > t2.ID AND
t1.parameter = t2.parameter
GROUP BY
t1.ID,
t2.ID
HAVING
COUNT(*) = (SELECT COUNT(*) FROM @tab AS dupe WHERE dupe.ID = t1.ID) AND
COUNT(*) = (SELECT COUNT(*) FROM @tab AS dupe WHERE dupe.ID = t2.ID)
);
Kết quả trên SQL Server 2008 R2:
num_groups
3
Đối với đối tượng với 0 thông số, nó phụ thuộc vào cách chúng được lưu trữ, nhưng nói chung, bạn muốn chỉ cần thêm một đến trả lời ở trên nếu có bất kỳ đối tượng nào có tham số 0.
Nguồn
2010-06-12 09:45:14
Làm thế nào để bạn đại diện zero thông số? Một NULL trong cột 'parameters' và một ràng buộc hoặc trigger để ngăn chặn bất kỳ phi NULL nào với cùng một' id'? – pilcrow
@pilcrow: Chắc chắn, có một bảng khác với id đối tượng làm khóa chính. – Eduardo