2012-11-18 17 views
8

कहें कि मेरे पास 3 फ़ील्ड: 'प्लेस', 'उपयोगकर्ता' और 'बाइट्स' के साथ एक साधारण टेबल है। आइए मान लें कि कुछ फ़िल्टर के तहत, मैं 'प्लेस' और प्रत्येक 'प्लेस' के लिए समूह करना चाहता हूं, उस स्थान के लिए सभी बाइट्स को समेटने के लिए, और यादृच्छिक रूप से उस स्थान के लिए उपयोगकर्ता का चयन करें (समान रूप से फिट सभी उपयोगकर्ताओं से 'जहां' फ़िल्टर और प्रासंगिक 'जगह')। अगर वहाँ था एक एकीकृत फ़ंक्शन "से बेतरतीब ढंग से चुनें", मुझे क्या करना होगा:एसक्यूएल यादृच्छिक कुल

SELECT place, SUM(bytes), SELECT_AT_RANDOM(user) WHERE .... GROUP BY place; 

... लेकिन मैं इस तरह के एक एकीकृत फ़ंक्शन नहीं पा सके। क्या मैं कुछ भूल रहा हूँ? इसे हासिल करने का एक अच्छा तरीका क्या हो सकता है?

+4

यह आरडीबीएमएस क्या है? –

+0

मुझे इस तरह के एक समारोह के साथ किसी भी व्यक्तिगत आरडीबीएमएस के बारे में पता नहीं है। अधिकतर परिणाम प्राप्त करने के लिए किसी अन्य तंत्र का उपयोग करने की आवश्यकता है * (जैसे कि प्रत्येक उपयोगकर्ता को यादृच्छिक संख्या असाइन करना, फिर उपयोगकर्ता को उच्चतम मूल्य के साथ चुनना।) * लेकिन प्रत्येक की अलग-अलग क्षमताएं होंगी, और प्रत्येक अलग-अलग प्रदर्शन करेगा। तो, यह वास्तव में एक आरडीबीएमएस विशिष्ट सवाल है। – MatBailie

+0

यदि आप MySQL का उपयोग कर रहे हैं तो बस गलत 'ग्रुप बाय' लिखें (उदा। उपयोगकर्ता पर कुल लागू न करें) और यह यादृच्छिक रूप से एक पंक्ति का चयन करेगा। –

उत्तर

5

यदि आपका आरडीबीएमएस विश्लेषणात्मक कार्यों का समर्थन करता है।

WITH T 
    AS (SELECT place, 
       Sum(bytes) OVER (PARTITION BY place) AS Sum_bytes, 
       user, 
       Row_number() OVER (PARTITION BY place ORDER BY random_function()) AS RN 
     FROM YourTable 
     WHERE ....) 
SELECT place, 
     Sum_bytes, 
     user 
FROM T 
WHERE RN = 1; 

एसक्यूएल सर्वर Crypt_gen_random(4) के लिए या NEWID() कुछ है कि random_function()

2

के लिए में प्रतिस्थापित किया जा सकता है, उदाहरण होगा मुझे लगता है कि आपके सवाल का डीबीएमएस विशिष्ट है। यादृच्छिक क्रम में

SELECT place_rand.place, SUM(place_rand.bytes), place_rand.user as random_user 
FROM 
    (SELECT place, bytes, user 
    FROM place 
    WHERE ... 
    ORDER BY rand()) place_rand 
GROUP BY 
    place_rand.place; 

सबक्वेरी आदेश रिकॉर्ड: यदि आपका डीबीएमएस MySql है, तो आप इस तरह एक समाधान का उपयोग कर सकते हैं। place द्वारा बाहरी क्वेरी समूह, bytes पर रकम करते हैं, और पहले यादृच्छिक उपयोगकर्ता लौटाते हैं, क्योंकि उपयोगकर्ता कुल कार्य में नहीं है और न ही समूह द्वारा खंड में।

0

मैं मार्टिन समाधान पर एक बदलाव का एक सा करना होगा:

select place, sum(bytes), max(case when seqnum = 1 then user end) as random_user 
from (select place, bytes, 
      row_number() over (partition by place order by newid()) as sequm 
     from t 
    ) t 
group by place 

कुछ के लिए (कहाँ newid() सिर्फ एक ही रास्ता है डेटाबेस के आधार पर एक यादृच्छिक संख्या प्राप्त करने के लिए, है।) कारण, मैं इस दृष्टिकोण को पसंद करता हूं, क्योंकि इसमें अभी भी बाहरी क्वेरी में एकत्रीकरण कार्य है। यदि आप खेतों का एक समूह सारांशित कर रहे हैं, तो यह मेरे लिए क्लीनर लगता है।

0

एक कस्टम योग समारोह के साथ, आप भाव लिखने के रूप में सरल रूप में हो सकते हैं:

SELECT place, SUM(bytes), SELECT_AT_RANDOM(user) WHERE .... GROUP BY place; 

SELECT_AT_RAMDOM कस्टम योग समारोह होगा।

यहाँ PostgreSQLमें ठीक an implementation है।