2014-05-02 19 views
5

tôi cần để xếp hạng hàng bằng cách phân vùng (hoặc nhóm), tức là nếu bảng nguồn của tôi là:Nhận số tuần tự của một hàng (cấp bậc) trong một phân vùng mà không sử dụng ROW_NUMBER() OVER chức năng

NAME PRICE 
---- ----- 
AAA 1.59 
AAA 2.00 
AAA 0.75 
BBB 3.48 
BBB 2.19 
BBB 0.99 
BBB 2.50 

tôi sẽ thích để có được bảng mục tiêu:

RANK NAME PRICE 
---- ---- ----- 
1 AAA 0.75 
2 AAA 1.59 
3 AAA 2.00 
1 BBB 0.99 
2 BBB 2.19 
3 BBB 2.50 
4 BBB 3.48 

Thông thường tôi sẽ sử dụng ROW_NUMBER() OVER chức năng, vì vậy trong Apache Hive nó sẽ là:

select 
    row_number() over (partition by NAME order by PRICE) as RANK, 
    NAME, 
    PRICE 
from 
    MY_TABLE 
; 

Thật không may Cloudera Impala không hỗ trợ (tại thời điểm này) ROW_NUMBER() OVER chức năng, vì vậy tôi đang tìm một cách giải quyết khác. Tốt hơn là không sử dụng UDAF, vì sẽ rất khó thuyết phục để triển khai nó vào máy chủ.

Cảm ơn sự giúp đỡ của bạn.

+1

phân tích chức năng cửa sổ là ưu tiên hàng đầu và đang phát triển. Tiếp tục theo dõi bản phát hành sắp tới, thêm chức năng này như là một phần của lộ trình cho Impala 2.0. – Matt

Trả lời

2

Cách giải quyết thông thường cho các hệ thống không hỗ trợ chức năng cửa sổ là một cái gì đó như thế này:

select name, 
     price, 
     (select count(*) 
     from my_table t2 
     where t2.name = t1.name -- this is the "partition by" replacement 
     and t2.price < t1.price) as row_number 
from my_table t1 
order by name, price; 

dụ SQLFiddle: http://sqlfiddle.com/#!2/3b027/2

+0

Tôi đã thử điều này, nhưng tiếc là Impala không hỗ trợ các truy vấn con tại thời điểm này. –

3

Nếu bạn không thể làm điều đó với một subquery tương quan, bạn vẫn có thể làm được điều này với một tham gia:

select t1.name, t1.price, 
     coalesce(count(t2.name) + 1, 1) 
from my_table t1 join 
    my_table t2 
    on t2.name = t1.name and 
     t2.price < t1.price 
order by t1.name, t1.price; 

Lưu ý rằng điều này không chính xác làm row_number()trừ tất cả các mức giá đều khác nhau cho một name nhất định. Công thức này thực sự tương đương với rank().

Đối với row_number(), bạn cần một số nhận dạng hàng duy nhất.

Bằng cách này, sau đây là tương đương với dense_rank():

select t1.name, t1.price, 
     coalesce(count(distinct t2.name) + 1, 1) 
from my_table t1 join 
    my_table t2 
    on t2.name = t1.name and 
     t2.price < t1.price 
order by t1.name, t1.price; 
+0

Thay vì sử dụng một tham gia bên trong cũng là một tham gia bên trái là có thể, nơi phần "coalesce (..., 1) có thể được giảm xuống. –

0

Không thực sự là một câu trả lời về cách với Impala, nhưng có SQL khác về những giải pháp Hadoop mà làm tùy chọn phân tích và subquery rồi. Nếu không có các khả năng đó, bạn có thể sẽ phải dựa vào quy trình đa bước hoặc một số UDAF.

Tôi là kiến ​​trúc sư cho InfiniDB
InfiniDB hỗ trợ chức năng phân tích và truy vấn phụ.
http://infinidb.co

Kiểm tra truy vấn 8 trong chuẩn từ Radiant Advisors, đây là truy vấn kiểu tương tự mà bạn đang sử dụng, sử dụng chức năng phân tích xếp hạng. Presto cũng có thể chạy truy vấn kiểu này, chỉ cần ở một chậm hơn (80x) với tốc độ http://radiantadvisors.com/wp-content/uploads/2014/04/RadiantAdvisors_Benchmark_SQL-on-Hadoop_2014Q1.pdf

Truy vấn từ điểm chuẩn (query 8)

SELECT 
    sub.visit_entry_idaction_url, 
    sub.name, 
    lv.referer_url, 
    sum(visit_ total_time) total_time, 
    count(sub.idvisit), 
    RANK() OVER (PARTITION BY sub. visit_entry_idaction_url 
ORDER BY 
    count(sub.idvisit)) rank_by_visits, 
    DENSE_RANK() OVER (PARTITION BY sub.visit_entry_idaction_url 
ORDER BY 
    count(visit_total_time)) rank_by_ time_spent 
FROM 
    log_visit lv, 
    (
SELECT 
    visit_entry_idaction_url, 
    name, 
    idvisit 
FROM 
    log_visit JOIN log_ action 
     ON 
     (visit_entry_idaction_url = log_action.idaction) 
WHERE 
    visit_ entry_idaction_url between 2301400 AND 
    2302400) sub 
WHERE 
    lv.idvisit = sub.idvisit 
GROUP BY 
    1, 2, 3 
ORDER BY 
    1, 6, 7; 

Kết quả

Hive 0.12  Not Executable 
Presto 0.57  506.84s 
InfiniDB 4.0 6.37s 
Impala 1.2  Not Executable 
Các vấn đề liên quan