2016-12-14 24 views
7

Tôi có một bảng trong SQL trông như thế này:Cách chọn giá trị thường xuyên nhất trong một cột cho mỗi nhóm id?

user_id | data1 
0  | 6 
0  | 6 
0  | 6 
0  | 1 
0  | 1 
0  | 2 
1  | 5 
1  | 5 
1  | 3 
1  | 3 
1  | 3 
1  | 7 

Tôi muốn viết một truy vấn mà trả về hai cột: một cột cho user id, và một cột cho những gì giá trị thường xuyên xảy ra nhất mỗi id Là. Trong ví dụ của tôi, cho user_id 0, giá trị thường gặp nhất là 6, và cho user_id 1, giá trị thường gặp nhất là 3. Tôi sẽ muốn nó trông giống như dưới đây:

user_id | most_frequent_value 
0  | 6 
1  | 3 

Tôi đang sử dụng các truy vấn dưới đây để nhận được giá trị thường xuyên nhất, nhưng nó chạy trên toàn bộ bảng và trả về giá trị phổ biến nhất cho toàn bộ bảng thay vì cho mỗi id. Tôi cần thêm điều gì vào truy vấn của mình để truy vấn trả về giá trị thường xuyên nhất cho mỗi id? Tôi nghĩ rằng tôi cần phải sử dụng một truy vấn phụ, nhưng không chắc chắn về cách cấu trúc nó.

SELECT user_id, data1 AS most_frequent_value 
FROM my_table 
GROUP BY user_id, data1 
ORDER BY COUNT(*) DESC LIMIT 1 
+1

Điều gì về hòa? (ví dụ: bạn thêm hàng '(0, 1)' vào ví dụ của bạn; sau đó cả hai '6' và' 1' là giá trị thường xuyên nhất, bởi vì cả hai giá trị này xuất hiện 3 lần). – pozs

Trả lời

2

Nếu bạn sử dụng đúng "thứ tự" thì distinct on (user_id) thực hiện cùng một công việc vì nó lấy 1.line từ dữ liệu được phân đoạn bởi "user_id". DISTINCT ON là đặc sản của PostgreSQL.

select distinct on (user_id) user_id, most_frequent_value from (
SELECT user_id, data1 AS most_frequent_value, count(*) as _count 
FROM my_table 
GROUP BY user_id, data1) a 
ORDER BY user_id, _count DESC 
+0

tôi có thể biết tại sao -1? Bởi vì tôi đã thử nghiệm nó trên examle này và tôi sử dụng cùng một truy vấn thường xuyên .... – JosMac

+0

Điều này làm việc tuyệt vời - cảm ơn bạn! Tôi cũng muốn biết tại sao nó có một phiếu bầu -1 (không phải tôi) – cjh193

+0

Điều này có thể hiệu quả nếu OP không quan tâm đến việc rút thăm. – pozs

1

Bạn có thể sử dụng chức năng cửa sổ để xếp hạng người dùng dựa trên số lượng dữ liệu của họ1.

; WITH cte AS (
SELECT 
    user_id 
    , data1 
    , ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY COUNT(data1) DESC) rn 
FROM dbo.YourTable 
GROUP BY 
    user_id, 
    data1) 

SELECT 
    user_id, 
    data1 
FROM cte WHERE rn = 1 
2

Với postgres 9.4 hoặc cao hơn có thể. Bạn có thể sử dụng nó như:

SELECT 
    user_id, MODE() WITHIN GROUP (ORDER BY value) 
FROM 
    (VALUES (0,6), (0,6), (0, 6), (0,1),(0,1), (1,5), (1,5), (1,3), (1,3), (1,7)) 
    users (user_id, value) 
GROUP BY user_id 
Các vấn đề liên quan