2012-02-22 18 views
22

मैं छत्ताहाइव क्वेरी

उपयोगकर्ता के आईडी, उपयोगकर्ता के नाम, उपयोगकर्ता के पते, क्लिक, इंप्रेशन, पेज आईडी, पेज-नाम

मैं में तालिका निम्नलिखित है द्वारा समूह में शीर्ष n रिकॉर्ड हो रही प्रत्येक पृष्ठ के लिए क्लिक करके शीर्ष 5 उपयोगकर्ताओं [उपयोगकर्ता-आईडी, उपयोगकर्ता नाम, उपयोगकर्ता-पता] को खोजने की आवश्यकता है [पेज-आईडी, पेज-नाम]

मैं समझता हूं कि हमें पहले पृष्ठ [पृष्ठ- आईडी, पेज-नाम] और प्रत्येक समूह के भीतर मैं ऑर्डर करना चाहता हूं [क्लिक, इंप्रेशन] desc और फिर प्रत्येक पृष्ठ के लिए केवल शीर्ष 5 उपयोगकर्ताओं [उपयोगकर्ता-आईडी, उपयोगकर्ता नाम, उपयोगकर्ता-पता] को छोड़ दें लेकिन मुझे यह मुश्किल लगता है क्वेरी का निर्माण करें।

हम इसे HIve UDF का उपयोग करके कैसे कर सकते हैं?

उत्तर

9

आप एक रैंक के साथ यह कर सकते हैं() यूडीएफ यहाँ वर्णित के रूप द्वारा @Himanshu गहलोत

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 

नोट उल्लेख 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

हाय मैक्सिमे, इस तरह आपको परेशान कर के लिए खेद है: आप नीचे दिए गए क्वेरी

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 

परिणाम उपयोग कर सकते हैं। मुझे भी इसी तरह की समस्या है। मैंने एसओ पर पोस्ट किया है, लेकिन मुझे कोई अच्छी प्रतिक्रिया नहीं मिली है क्योंकि मैं हाइव और हिवेक्यूएल के साथ काम कर रहा हूं, मेरे लिए नया है। [http://stackoverflow.com/questions/11405446/find-10-latest-record-for-each-buyer-id-for-yesterdays-date](http://stackoverflow.com/questions/11405446/find- 10-नवीनतम रिकॉर्ड के लिए प्रत्येक-खरीदार-आईडी के लिए कल की तारीख)। यह मेरे लिए बहुत मददगार होगा। – ferhan

+9

मैंने बस इस काम को बनाने में घंटों लगाए लेकिन यह काम नहीं किया। बग यह है कि आप पहली रैंकिंग कर रहे हैं और फिर डिस्ट्रिब्यूट द्वारा और सॉर्ट कर रहे हैं। इसके बजाय आपको बाहरी क्वेरी में रैंक लागू करना चाहिए और आंतरिक क्वेरी में DISTRIBUTE BY और SORT का उपयोग करना चाहिए। उदाहरण के लिए, चयन पृष्ठ-आईडी, उपयोगकर्ता-आईडी, क्लिक करें (चयन पृष्ठ-आईडी, उपयोगकर्ता-आईडी, रैंक (उपयोगकर्ता-आईडी) रैंक के रूप में, क्लिक करें (चयन करें * पृष्ठ-आईडी, उपयोगकर्ता आईडी आईडी द्वारा मेरेटेबल वितरण से चुनें पेज-आईडी द्वारा, उपयोगकर्ता-आईडी, डीईएससी पर क्लिक करता है) ए) बी WHERE रैंक <5 ऑर्डर पृष्ठ-आईडी, रैंक; –

+2

ने पुष्टि की कि @ हिमांशु गहलोत सही है। जवाब में एक * बग * है! आपको बाहरी क्वेरी में रैंक() का उपयोग करना होगा और आंतरिक क्वेरी में DISTRIBUTE/SORT का उपयोग करना होगा! –

15

संशोधित जवाब, बग फिक्सिंग कि रैंक() यूडीएफ़ को पेज-आईडी कॉलम पर लागू किया जाता है, जिसका नया मान रैंक काउंटर को रीसेट या बढ़ाने के लिए उपयोग किया जाता है (उदाहरण के लिए प्रत्येक पृष्ठ-आईडी विभाजन के लिए रीसेट काउंटर)

+0

कूल .. यह मेरी खोज को बचाया :) – minhas23

9

हाइव 0.11 के रूप में, आप thi कर सकते हैं Hive के रैंक() फ़ंक्शन में निर्मित और Hive's built-in Analytics and Windowing functions का उपयोग करके सरल अर्थशास्त्र का उपयोग कर रहा है। अफसोस की बात है, मुझे इनके साथ कई उदाहरण नहीं मिल सका क्योंकि मुझे पसंद आया होगा, लेकिन वे वास्तव में वास्तव में उपयोगी हैं। उन का उपयोग करना, दोनों रैंक() और WhereWithRankCond में निर्माण कर रहे हैं, तो आप सिर्फ कर सकते हैं:

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 

नहीं यूडीएफ की आवश्यकता है, और केवल एक ही सबक्वेरी! इसके अलावा, सभी रैंक तर्क स्थानीयकृत है।

आप इन कार्यों के उदाहरण in this Jira और this guy's blog पर कुछ और (हालांकि मेरी पसंद के लिए पर्याप्त नहीं) पा सकते हैं।

2

आप अपाचे हाइव पर एक कुशल शीर्ष-के गणना के लिए hivemall के each_top_k function का उपयोग कर सकते हैं।

 
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 

each_top_k UDTF बहुत तेजी से जब हाइव में शीर्ष कश्मीर प्रश्नों (जैसे, distributed by/rank) चल अन्य तरीकों की तुलना में, क्योंकि यह मध्यवर्ती परिणाम के लिए पूरे रैंकिंग पकड़ नहीं करता है।

1

हम कहते हैं कि आपके डेटा की तरह लग रहा हैं निम्नलिखित:

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 

क्वेरी नीचे आप दे देंगे:

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 

परिणाम:

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 

तो, पृष्ठ 1 के लिए आप 6 हो रही है उपयोगकर्ता, समान क्लिक वाले उपयोगकर्ताओं के समान स्थान पर हैं।

लेकिन, यदि आप बिल्कुल 5 उपयोगकर्ताओं की तलाश में हैं, और कई उपयोगकर्ताओं को समान रैंक में गिरावट के मामले में यादृच्छिक रूप से चुनें।

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 
संबंधित मुद्दे