2012-02-22 37 views
22

Tôi đã theo bảng trong hiveHive nhận hồ sơ n hàng đầu trong nhóm bằng cách truy vấn

sử dụng id, user-name, sử dụng địa chỉ, nhấp chuột, hiển thị, trang-id, trang tên tuổi

tôi cần tìm ra 5 người dùng hàng đầu [id người dùng, tên người dùng, địa chỉ người dùng] theo số nhấp chuột cho mỗi trang [tên trang, tên trang]

Tôi hiểu rằng chúng ta cần phải nhóm đầu tiên theo [trang- id, tên trang] và trong mỗi nhóm tôi muốn orderby [nhấp chuột, hiển thị] desc và sau đó chỉ phát ra 5 người dùng hàng đầu [id người dùng, tên người dùng, địa chỉ người dùng] cho mỗi trang nhưng tôi thấy khó khăn xây dựng truy vấn.

Làm cách nào chúng tôi có thể thực hiện việc này bằng cách sử dụng UDve UDF?

Trả lời

9

Bạn có thể làm điều đó với một cấp bậc() UDF mô tả ở đây: http://ragrawal.wordpress.com/2011/11/18/extract-top-n-records-in-each-group-in-hadoophive/

SELECT page-id, user-id, clicks 
FROM (
    SELECT page-id, user-id, rank(user-id) as rank, clicks 
    FROM mytable 
    DISTRIBUTE BY page-id, user-id 
    SORT BY page-id, user-id, clicks desc 
) a 
WHERE rank < 5 
ORDER BY page-id, rank 
+0

Hi Maxime, Xin lỗi vì làm phiền bạn như thế này. Tôi cũng gặp vấn đề tương tự. Tôi đã đăng trên SO, nhưng không có bất kỳ phản ứng tốt như tôi đang làm việc với Hive và HiveQL là mới đối với tôi. [http://stackoverflow.com/questions/11405446/find-10-latest-record-for-each-buyer-id-for-yesterdays-date](http://stackoverflow.com/questions/11405446/find- 10-mới nhất-ghi-cho-mỗi-người mua-id-cho-yesterdays-ngày). Nó sẽ giúp ích rất nhiều cho tôi. – ferhan

+9

Tôi chỉ cần bỏ ra hàng giờ để thực hiện công việc này nhưng nó không hoạt động. Lỗi là bạn đang xếp hạng đầu tiên và sau đó làm DISTRIBUTE BY và SORT BY. Thay vào đó, bạn nên áp dụng xếp hạng trong truy vấn bên ngoài và sử dụng DISTRIBUTE BY và SORT BY trong truy vấn bên trong. Ví dụ, SELECT page-id, user-id, click FROM (SELECT page-id, user-id, rank (user-id) làm thứ hạng, nhấn FROM (SELECT * FROM mytable DISTRIBUTE BY page-id, user-id SORT THEO page-id, user-id, click DESC) a) b WHERE rank <5 ORDER BY page-id, rank; –

+2

Xác nhận rằng @HimanshuGahlot là chính xác. Câu trả lời có * BUG *! Bạn phải sử dụng thứ hạng() trong truy vấn bên ngoài và sử dụng DISTRIBUTE/SORT BY trong truy vấn bên trong! –

15

câu trả lời Revised, sửa chữa các lỗi như đã đề cập bởi @Himanshu Gahlot

SELECT page-id, user-id, clicks 
FROM (
    SELECT page-id, user-id, rank(page-id) as rank, clicks FROM (
     SELECT page-id, user-id, clicks FROM mytable 
     DISTRIBUTE BY page-id 
     SORT BY page-id, clicks desc 
) a) b 
WHERE rank < 5 
ORDER BY page-id, rank 

Lưu ý rằng cấp bậc() UDAF được áp dụng cho cột id trang, có giá trị mới được sử dụng để đặt lại hoặc tăng bộ đếm thứ hạng (ví dụ: bộ đếm đặt lại cho từng phân đoạn trang-id)

+0

Cool .. Nó đã lưu tìm kiếm của tôi :) – minhas23

9

Kể từ khi Hive 0,11, bạn có thể thực hiện s sử dụng hàm xếp hạng() của Hive và sử dụng ngữ nghĩa đơn giản hơn bằng cách sử dụng Hive's built-in Analytics and Windowing functions. Đáng buồn thay, tôi không thể tìm thấy nhiều ví dụ như những gì tôi thích, nhưng chúng thực sự rất hữu ích. Sử dụng những, cả hai cấp bậc() và WhereWithRankCond được xây dựng trong, vì vậy bạn chỉ có thể làm: cần

SELECT page-id, user-id, clicks 
FROM (
    SELECT page-id, user-id, rank() 
      over (PARTITION BY page-id ORDER BY clicks DESC) as rank, clicks 
    FROM my table 
) ranked_mytable 
WHERE ranked_mytable.rank < 5 
ORDER BY page-id, rank 

Không UDF, và chỉ có một subquery! Ngoài ra, tất cả logic xếp hạng đều được bản địa hóa.

Bạn có thể tìm thấy một số ví dụ khác (mặc dù không đủ cho ý thích của tôi) về các chức năng này in this Jira và trên this guy's blog.

2

Bạn có thể sử dụng each_top_k function trong số hivemall để tính toán hiệu quả hàng đầu trên Apache Hive.

 
select 
    page-id, 
    user-id, 
    clicks 
from (
    select 
    each_top_k(5, page-id, clicks, page-id, user-id) 
     as (rank, clicks, page-id, user-id) 
    from (
    select 
     page-id, user-id, clicks 
    from 
     mytable 
    DISTRIBUTE BY page-id SORT BY page-id 
) t1 
) t2 
order by page-id ASC, clicks DESC 

Các each_top_k UDTF rất nhanh khi so sánh với các phương pháp khác chạy các truy vấn hàng đầu k (ví dụ, distributed by/rank) trong Hive bởi vì nó không giữ toàn bộ xếp hạng cho kết quả trung gian.

1

Chúng ta hãy nói dữ liệu của bạn trông giống như sau:

page-id user-id clicks 
page1  user1  10 
page1  user2  10 
page1  user3  9 
page1  user4  8 
page1  user5  7 
page1  user6  7 
page1  user7  6 
page1  user8  5 
page2  user1  20 
page2  user2  19 
page2  user3  18 

Dưới Query sẽ cung cấp cho bạn:

SELECT page-id, user-id, clicks, rank 
FROM (
    SELECT page-id, user-id, rank() 
      over (PARTITION BY page-id ORDER BY clicks DESC) as rank, clicks 
    FROM your_table 
) ranked_table 
WHERE ranked_table.rank <= 5 

Kết quả:

page-id user-id clicks rank 
page1  user1  10  1 
page1  user2  10  1 
page1  user3  9  3 
page1  user4  8  4 
page1  user5  7  5 
page1  user6  7  5 
page2  user1  20  1 
page2  user2  19  2 
page2  user3  18  3 

Vì vậy, ví page1 bạn đang nhận được 6 người dùng, vì người dùng có cùng số lần nhấp được xếp hạng giống nhau.

Nhưng, nếu bạn đang tìm chính xác 5 người dùng và chọn ngẫu nhiên trong trường hợp nhiều người dùng thuộc cùng một cấp bậc.Bạn có thể sử dụng truy vấn dưới đây

SELECT page-id, user-id, clicks, rank 
FROM (
    SELECT page-id, user-id, row_number() 
      over (PARTITION BY page-id ORDER BY clicks DESC) as rank, clicks 
    FROM your_table 
) ranked_table 
WHERE ranked_table.rank <= 5 

Kết quả:

page-id user-id clicks rank 
page1  user1  10  1 
page1  user2  10  2 
page1  user3  9  3 
page1  user4  8  4 
page1  user5  7  5 
page2  user1  20  1 
page2  user2  19  2 
page2  user3  18  3 
Các vấn đề liên quan