2010-06-20 13 views
6

एक बेहतर तरीका है यह एक एसक्यूएल दक्षता प्रश्न है।एसक्यूएल उप प्रश्न - क्या

कुछ समय पहले मुझे ईआरपी सिस्टम से डेटा खींचने के लिए प्रश्नों का संग्रह लिखना पड़ा। इनमें से अधिकतर काफी सरल थे, लेकिन उनमें से एक के बजाय एक अपरिहार्य क्वेरी हुई और यह तब से मुझे परेशान कर रहा था क्योंकि एक बेहतर तरीका होना चाहिए।

समस्या जटिल नहीं है। आपके पास बिक्री डेटा की पंक्तियां हैं। प्रत्येक पंक्ति में आपके पास मात्रा, बिक्री मूल्य और विक्रेता कोड है, अन्य जानकारी के साथ।

आयोग को एक चरणबद्ध स्लाइडिंग पैमाने पर आधारित भुगतान किया जाता है। जितना अधिक वे बेचते हैं, आयोग बेहतर होता है। कदम 1000, 10000, 10000 $ और बहुत आगे हो सकते हैं। वास्तविक दुनिया की समस्या अधिक जटिल है लेकिन यह अनिवार्य रूप से यह है।

एक ही रास्ता मैं ऐसा करने का पाया कुछ इस तरह (स्पष्ट रूप से नहीं वास्तविक क्वेरी)

select qty, price, salesman, 
    (select top 1 percentage from comissions 
    where comisiones.salesman = saleslines.salesman 
    and saleslines.qty > comisiones.qty 
    order by comissiones.qty desc 
) percentage 
from saleslines 

यह सही आयोग में परिणाम है, लेकिन horrendously भारी है क्या करने के लिए किया गया था।

क्या ऐसा करने का कोई बेहतर तरीका है? मैं किसी को अपने एसक्यूएल को फिर से लिखने की तलाश नहीं कर रहा हूं, और 'फूबर प्रश्नों के रूप में एक नज़र डालें' और मैं इसे वहां से ले जा सकता हूं।

वास्तविक जीवन आयोग संरचना विभिन्न विक्रेता, लेख और ग्राहकों और यहां तक ​​कि बिक्री तिथियों के लिए निर्दिष्ट की जा सकती है। यह समय-समय पर भी बदलता है, इसलिए सबकुछ टेबल में डेटा द्वारा संचालित किया जाना चाहिए ... यानी मैं एसक्यूएल में निश्चित श्रेणियां नहीं डाल सकता। वर्तमान क्वेरी कुछ 3-400000 पंक्तियां लौटाती है और लगभग 20-30 सेकेंड लेती है। सौभाग्य से इसका मासिक इस्तेमाल किया जाता है लेकिन धीमापन मुझे थोड़ी परेशान कर रहा है।

यह mssql पर है।

इयान

संपादित करें:

मैं शुरू से ही एक अधिक जटिल उदाहरण देना चाहिए। मुझे अब एहसास है कि मेरे शुरुआती उदाहरण में जटिलता के कुछ आवश्यक तत्व गायब हैं, सभी के लिए क्षमा चाहते हैं।

यह बेहतर यह

select client-code, product, product-family, qty, price, discount, salesman, 
    (select top 1 percentage from comissions 
     where comisiones.salesman = saleslines.salesman 
     and saleslines.qty > comisiones.qty 
     and [ 
      a collection of conditions which may or may not apply: 
      Exclude rows if the salesman has offered discounts above max discounts 
       which appear in each row in the commissions table 
      There may be a special scale for the product family 
      There may be a special scale for the product 
      There may be a special scale for the client 

      A few more cases 
      ] 
     order by [ 
      The user can control the order though a table 
      which can prioritize by client, family or product 
      It normally goes from most to least specific. 
      ] 
    ) percentage 
    from saleslines 

अनावश्यक पर कब्जा कर सकते हैं कहने के लिए वास्तविक क्वेरी का पालन करने के लिए आसान नहीं है। जीवन को और अधिक रोचक बनाने के लिए, इसका नामकरण बहु भाषा है।

इस प्रकार बिक्री की प्रत्येक पंक्ति के लिए कमीशन अलग हो सकता है।

यह अत्यधिक जटिल लग सकता है लेकिन यदि आप सोचते हैं कि आप कमीशन का भुगतान कैसे करेंगे, तो यह समझ में आता है। आप किसी को उच्च छूट पर सामान बेचने के लिए भुगतान नहीं करना चाहते हैं, तो आप एक्स विशेषताओं को एक विशेष उत्पाद पर छूट देने में सक्षम होना चाहते हैं यदि वे एक्स इकाइयां खरीदते हैं। अगर वे अधिक बिकते हैं तो विक्रेता को अधिक कमाई करनी चाहिए।

उपर्युक्त में मैं तारीख सीमित विशेष ऑफ़र को छोड़ रहा हूं।

मुझे लगता है कि विभाजन समाधान हो सकता है लेकिन मुझे विभाजन के बारे में कुछ भी पता नहीं है क्योंकि मुझे यह और अधिक जानकारी मिलनी है। यह मुझे कुछ विचार दिया।

+0

अगर इसकी केवल मासिक चलाने के लिए, मैं इसके बारे में चिंता नहीं करता: जब उस खास विक्रेता जहां SalesLine.Qty> Commission.Qty, तो आप की तरह कुछ कर सकता है के लिए कोई आयोग मान हैं। ऐसा लगता है कि इसे कई बड़ी टेबलों पर बहुत सी गणना करना है। यदि इसे अधिक बार चलाना पड़ता है, तो हो सकता है कि आप एक अलग रणनीति का उपयोग करके परिणाम सेट को बढ़ाना चाहें। –

+0

कभी-कभी वास्तव में काम को मापना बेहतर होता है और इंडेक्स या तेज़ डिस्क इत्यादि जैसे बेहतर बुनियादी ढांचे का परिचय देता है। आपको क्वेरी प्रोफाइल करना चाहिए और देखें कि बिट्स भारी हैं। –

+0

SQL सर्वर का कौन सा संस्करण आप उपयोग कर रहे हैं? –

उत्तर

3

आपको लगता है कि इस तरह के SQL सर्वर 2005 और बाद में के रूप में आम-टेबल भाव का समर्थन करता है SQL सर्वर के एक संस्करण का उपयोग कर रहे हैं, तो एक अधिक कुशल समाधान हो सकता है:

With RankedCommissions As 
    (
    Select SL.qty, SL.price, SL.salesman, C.percentage 
     , Row_Number() Over (Partition By SL.salesman Order By C.Qty Desc) As CommissionRank 
    From SalesLines As SL 
     Join Commissions As C 
      On SL.salesman = C.salesman 
       And SL.qty > C.qty 
    ) 
Select qtr, price, salesman, percentage 
From RankedCommissions 
Where CommissionRank = 1 

आप संभावना के लिए खाते में करने के लिए आवश्यक हैं कि

With RankedCommissions As 
    (
    Select SL.qty, SL.price, SL.salesman, C.percentage 
     , Row_Number() Over (Partition By SL.salesman Order By C.Qty Desc) As CommissionRank 
    From SalesLines As SL 
     Join Commissions As C 
      On SL.salesman = C.salesman 
       And SL.qty > C.qty 
    ) 
Select SL.qtr, SL.price, SL.salesman, RC.percentage 
From SalesLines As SL 
    Left Join RankedCommissions As RC 
     On RC.salesman = SL.salesman 
      And RC.CommissionRank = 1 
+0

इस दृष्टिकोण का उपयोग करने के लिए आपको सामान्य-सारणी अभिव्यक्तियों के समर्थन के लिए * आवश्यकता नहीं है *। आप आसानी से सीटीई को एक इनलाइन व्यू के रूप में लिख सकते हैं। हालांकि, 'ROW_NUMBER' फ़ंक्शन को SQL Server 2005 या उच्चतर की आवश्यकता होती है। –

+0

मेरी मूल क्वेरी sql2000 के लिए लिखी गई थी लेकिन डीबी हाल ही में sql2008 में माइग्रेट की गई, जो नई कार्यक्षमता का लाभ उठाने में मेरी रुचि को उकसाया। थॉमस, यह एक समाधान की तरह दिखता है। हालांकि यह एक बहुत ही अलग दृष्टिकोण है इसलिए मुझे इसके साथ थोड़ी देर बैठना होगा और देखें कि मैं इसका उपयोग कैसे कर सकता हूं। समाधान की तरह। धन्यवाद- इयान – Ian

+0

@ इयान - समझें। ROW_Number जैसे सीटीई और रैंकिंग फ़ंक्शन 2005/2008 में अविश्वसनीय रूप से शक्तिशाली नई सुविधा हैं। वे आपके द्वारा प्रस्तुत किए गए समस्याग्रस्त प्रश्नों की श्रृंखला को सरल बनाने में सहायता करते हैं। मेरे समाधान में वास्तविक चाल विभाजन द्वारा विभाजन का उपयोग है जो विक्रेता (विक्रेता?) द्वारा मूल्यों का आदेश देती है। – Thomas

0
select 
    qty, price, salesman, 
    max(percentage) 
from saleslines 
    inner join comissions on commisions.salesman = saleslines.salesman and 
      saleslines.qty > comissions.qty 
group by 
    qty, price, salesman 
+0

-1, आपका कोड उच्चतम प्रतिशत देता है; मूल क्वेरी उच्चतम qty के लिए प्रतिशत देता है। – Gabe

+0

INNER जॉइन की एक शर्त (saleslines.qty> comissions.qty) है जो बिक्री की मात्रा क्वांटिया से अधिक मात्रा के साथ सभी कमिशन लाइनों को फ़िल्टर करती है। शेष पंक्तियों पर अधिकतम उच्चतम मात्रा (उच्चतम प्रतिशत नहीं) के लिए प्रतिशत देता है। – potatopeelings

+0

या तो मुझे लगता है :-) – potatopeelings

संबंधित मुद्दे