2011-10-28 36 views
6

Tôi đang cố gắng viết truy vấn sql cho biết tần suất hai đội chơi với nhau.Cách truy vấn đếm trên 2 cột

Id | Team1 | Team2 | Date 
1 | A | B | 25/5/11 
2 | B | A | 26/5/11 
3 | A | C | 27/5/11 
4 | C | B | 28/5/11 
5 | A | B | 28/5/11 

kết quả nên là:

A vs B => 3 
A vs C => 1 
C vs B => 1 

Đếm A-B và B-A như khác nhau là một truy vấn dễ dàng. Nhưng tôi không thể để chúng được tính cùng nhau.

Mọi đề xuất?

+0

Đội bóng có thể được bất cứ điều gì. Tôi đã sử dụng A và B để viết nhanh hơn. – Sorskoot

+0

có số đại diện cho mỗi đội không? tức là từ một bảng đội? – galchen

+0

Bạn đang sử dụng phiên bản SQL nào? – leoinfo

Trả lời

5
SELECT Team1, Team2, SUM(num) FROM (
    SELECT Team1, Team2, COUNT(*) num 
    FROM table_name 
    GROUP BY Team1, Team2 
    UNION ALL 
    SELECT Team2, Team1, COUNT(*) num 
    FROM table_name 
    GROUP BY Team2, Team1 
) combined 
WHERE Team1 < Team2 
GROUP BY Team1, Team2 

Chỉnh sửa: Cập nhật thành nhóm ngược lại khi cần.

Lưu ý: Điều này sẽ chạy nhanh hơn rất nhiều so với các phiên bản sử dụng CASE bạn đã được đưa ra trong các câu trả lời khác vì nó sẽ tận dụng tối đa các chỉ mục.

Chỉnh sửa2: Đã di chuyển đến vị trí còn nhanh hơn với chỉ mục.

+0

Điều đó sẽ không cho kết quả đúng. Có sự khác biệt giữa 'A -> B' và 'B -> A' trong truy vấn đó. OP đang tìm kiếm A vs B được kết hợp với B so với A. –

+0

Đó chính xác là điểm của tôi ... :) – Sorskoot

+0

@Shark Ah, bỏ lỡ điều đó. Không sao, cập nhật câu trả lời của tôi. – Ariel

6

Tôi đã sử dụng truy vấn phụ để sắp xếp lại nhóm trước khi nhóm.

SELECT first_team, second_team, count(*) 
FROM (
    SELECT 
     CASE WHEN Team1 < Team2 THEN Team1 ELSE Team2 END AS first_team, 
     CASE WHEN Team1 < Team2 THEN Team2 ELSE Team1 END AS second_team 
    FROM table 
) a 
GROUP BY first_team, second_team; 
+0

Thao tác này sẽ hoạt động nhưng không sử dụng chỉ mục, vì vậy nếu bạn có nhiều nhóm sử dụng câu trả lời của tôi. – Ariel

1
SELECT 
    (CASE WHEN Team1<Team2 THEN Team1 ELSE Team2) Team1, 
    (CASE WHEN Team1>Team2 THEN Team1 ELSE Team2) Team2, 
    COUNT(*) cnt 
FROM <table> 
GROUP BY 
    (CASE WHEN Team1<Team2 THEN Team1 ELSE Team2) Team1, 
    (CASE WHEN Team1>Team2 THEN Team1 ELSE Team2) Team2 
1

Có vài cách để đạt được mục tiêu của bạn:

SELECT Teams, Games = COUNT(*) FROM 
(
    SELECT 
    Teams = CASE WHEN Team1 < Team2 THEN Team1 ELSE Team2 END + ' vs ' + 
      CASE WHEN Team1 < Team2 THEN Team2 ELSE Team1 END 
    FROM MY_TABLE 
) AS T 
GROUP BY Teams 

OR, nếu bạn sử dụng SQL 2005/2008

;WITH T AS (
    SELECT 
    Teams = CASE WHEN Team1 < Team2 THEN Team1 ELSE Team2 END + ' vs ' + 
      CASE WHEN Team1 < Team2 THEN Team2 ELSE Team1 END 
    FROM MY_TABLE 
) 
SELECT Teams, Games = COUNT(*) FROM T GROUP BY Teams 

Cả hai điều trên sẽ cung cấp cho bạn cùng một kết quả

/* 
Teams  Games 
-------|------ 
A vs B 3 
A vs C 1 
B vs C 1 
*/ 

Dưới đây là một kịch bản mà bạn có thể chơi với:

/* TEST DATA */ 
DECLARE @t AS TABLE (ID INT, Team1 CHAR(1), Team2 CHAR(1), playdate [DATETIME]) 
INSERT INTO @t (Team1 , Team2 , playdate) 
      SELECT 'A' , 'B', '20110525' 
UNION ALL SELECT 'B' , 'A', '20110526'  
UNION ALL SELECT 'A' , 'C', '20110527'  
UNION ALL SELECT 'C' , 'B', '20110528'  
UNION ALL SELECT 'A' , 'B', '20110528'  


/* STYLE 1 */  
;WITH T AS (
    SELECT 
    Teams = CASE WHEN Team1 < Team2 THEN Team1 ELSE Team2 END + ' vs ' + 
      CASE WHEN Team1 < Team2 THEN Team2 ELSE Team1 END 
    FROM @t 
) 
SELECT Teams, Games = COUNT(*) FROM T GROUP BY Teams 

/* STYLE 2 */ 
SELECT Teams, Games = COUNT(*) FROM 
(
    SELECT 
    Teams = CASE WHEN Team1 < Team2 THEN Team1 ELSE Team2 END + ' vs ' + 
      CASE WHEN Team1 < Team2 THEN Team2 ELSE Team1 END 
    FROM @t 
) AS T 
GROUP BY Teams 

/* OR, sử dụng để chỉ cần chuyển các cột tên */

/* STYLE 3 */  
;WITH T AS (
    SELECT 
     Team1 = CASE WHEN Team1 < Team2 THEN Team1 ELSE Team2 END 
    , Team2 = CASE WHEN Team1 < Team2 THEN Team2 ELSE Team1 END 
    FROM @t 
) 
SELECT Team1 , Team2, Games = COUNT(*) FROM T GROUP BY Team1 , Team2 

/* STYLE 4 */ 
SELECT Team1 , Team2, Games = COUNT(*) FROM 
(
    SELECT 
     Team1 = CASE WHEN Team1 < Team2 THEN Team1 ELSE Team2 END 
    , Team2 = CASE WHEN Team1 < Team2 THEN Team2 ELSE Team1 END 
    FROM @t 
) AS T 
GROUP BY Team1 , Team2 
Các vấn đề liên quan