2010-12-16 98 views
7

मैं द्वारा विभाजित लोगों को रैंक कैसे करूं (संबंधों के साथ)?समूहबद्ध रैंकिंग करने के लिए एक्सेस एसक्यूएल का उपयोग करें

उदाहरण के लिए, इस तालिका को दिया गया है, मैं दाईं ओर रैंक कॉलम बनाना चाहता हूं। मुझे इसे एक्सेस में कैसे करना चाहिए?

 
SalesPerson Dept #Customers Rank 
Bill  DeptA  20 1 
Ted   DeptA  30 2 
Jane  DeptA  40 3 
Bill  DeptB  50 1 
Mary  DeptB  60 2 

मुझे पहले से ही पता है कि इस SQL ​​कोड के साथ एक सरल रैंकिंग कैसे करें। लेकिन मुझे नहीं पता कि समूह को स्वीकार करने के लिए इसे कैसे पुन: कार्य करना है।

Select Count(*) from [Tbl] Where [#Customers] < [Tblx]![#Customers])+1 

इसके अलावा, वहाँ इस का उपयोग करते हुए SQL सर्वर की वरीयता श्रेणी() फ़ंक्शन के लिए उत्तर के बहुत सारे है, लेकिन मैं Access में ऐसा करने की जरूरत है। सुझाव, कृपया?

उत्तर

12
SELECT *, (select count(*) from tbl as tbl2 where 
tbl.customers > tbl2.customers and tbl.dept = tbl2.dept) + 1 as rank from tbl 

बस नहीं सबक्वेरी के लिए विभाग फ़ील्ड जोड़ ...

+0

बस इतना आसान! – PowerUser

+0

क्या यह उन्हें सही तरीके से आदेश देता है, यद्यपि? दिलचस्प - पता नहीं था एक्सेस यह कर सकता है। क्या संस्करण, कृपया? साथ ही, जब तक आप डेटाबेस में कोई फ़ील्ड अपडेट नहीं करते हैं, तो आप जितनी चाहें उतनी बार इसे चलाने जा रहे हैं। –

0

आपको कुछ गणित करने की आवश्यकता है। मैं आमतौर पर काउंटर फील्ड और "ऑफसेट" फ़ील्ड के संयोजन का लाभ उठाता हूं। आपको एक तालिका जो इस तरह दिखता है के लिए लक्ष्य कर रहे हैं (#Customers आवश्यक नहीं है, लेकिन यह है कि आप इसे ठीक तरह से कर रहे हैं आप एक दृश्य दे देंगे):

SalesPerson Dept #Customers Ctr Offset 
Bill  DeptA  20 1 1 
Ted   DeptA  30 2 1 
Jane  DeptA  40 3 1 
Bill  DeptB  50 4 4 
Mary  DeptB  60 5 4 

तो, रैंक देने के लिए, आप चाहते करना [सीटीआर] - [ऑफसेट] +1 रैंक के रूप में

  1. निर्माण SalesPerson, Dept, Ctr के साथ एक मेज, और कहा कि तालिका में Offset
  2. डालने, Dept और #Customers (द्वारा आदेश दिया तो वे सब कर रहे हैं कि ठीक तरह से क्रमबद्ध)
  3. अद्यतन OffsetMIN(Ctr) होने के लिए, Dept
  4. पर समूहीकरण तालिका बाहर निर्धारित करने के लिए Rank
  5. साफ अपने गणित गणना प्रदर्शन करना है ताकि आप इसे फिर से अगली बार उपयोग करने के लिए तैयार हैं।
+0

मुझे नहीं पता कि यह काम करेगा या नहीं, लेकिन पंजाबॉट का समाधान काम करने के लिए आसान है और जाने के लिए तैयार है। – PowerUser

0

इस और किसी भी अन्य संबंधित पहुँच रैंकिंग या रैंक टाई ब्रेकर पहुँच के अन्य संस्करणों के लिए युक्तियां को जोड़ने के लिए, रैंकिंग चाहिए क्रॉस्स्टैब प्रश्नों पर प्रदर्शन किया जाए यदि आपके FROM खंड में कोई तालिका न हो, लेकिन एक क्वेरी जो क्रॉसस्टैब क्वेरी या उसके भीतर मौजूद एक क्वेरी है, कहीं और एक क्रॉसस्टैब क्वेरी है।

कोड जहां एक का चयन करें बयान के भीतर एक SELECT कथन प्रयोग किया जाता है (उप क्वेरी) ऊपर संदर्भित,

"SELECT *, (select count(*) from tbl as tbl2 where tbl.customers > tbl2.customers and tbl.dept = tbl2.dept) + 1 as rank from tbl" 

काम नहीं करेगा और हमेशा कोड जहां "tbl के भाग पर एक त्रुटि व्यक्त असफल हो जायेगी। ग्राहक>tbl2.customers " नहीं मिला।

पिछली परियोजना पर मेरी स्थिति में, मैं एक तालिका के बजाय एक क्वेरी का संदर्भ दे रहा था और उस क्वेरी के भीतर मैंने एक क्रॉसस्टैब क्वेरी का संदर्भ दिया था जिससे त्रुटि हुई और त्रुटि उत्पन्न हुई। मैं क्रॉसस्टैब क्वेरी से पहले एक टेबल बनाकर इसे हल करने में सक्षम था, और जब मैंने FROM खंड में नव निर्मित तालिका का संदर्भ दिया, तो उसने मेरे लिए काम करना शुरू कर दिया।

तो अंतिम रूप में, सामान्य रूप से आप चयन कथन के FROM खंड में एक क्वेरी या तालिका का संदर्भ दे सकते हैं जैसा कि पहले रैंकिंग करने के लिए साझा किया गया था, लेकिन सावधान रहें कि यदि आप किसी तालिका के बजाय किसी क्वेरी का संदर्भ दे रहे हैं, उस क्वेरी को नहीं एक क्रॉसस्टैब क्वेरी हो या किसी अन्य क्वेरी को संदर्भित करें जो एक क्रॉसस्टैब क्वेरी है।

उम्मीद है कि यह किसी और की मदद करता है, यदि आप ऊपर दिए गए बयानों का संदर्भ लेते हैं और आप अपने स्वयं के प्रोजेक्ट के भीतर अपने FROM खंड में किसी तालिका का संदर्भ नहीं दे रहे हैं तो संभावित कारण ढूंढने में समस्याएं हो सकती हैं। साथ ही, एक्सेस में क्रॉसस्टैब प्रश्नों के साथ उपनामों पर उप-निष्पादन निष्पादित करना संभवतः अच्छा विचार या सर्वोत्तम अभ्यास नहीं है, इसलिए यदि संभव हो तो उससे दूर भटक जाएं।

यदि आपको यह उपयोगी लगता है, और यह सुनिश्चित करना है कि एक्सेस एक पास्टस्ट्रू क्वेरी एडिटर में स्क्रोलिंग माउस के उपयोग की अनुमति दे, तो कृपया मुझे एक तरह दें।

1

सबक्वायरी के साथ महान समाधान! विशाल अभिलेखों को छोड़कर, सबक्वायरी समाधान बहुत धीमा हो जाता है। इसके बेहतर (तेज) एक स्व उपयोग करने के लिए शामिल हों, folowing समाधान को देखो: self join

SELECT tbl1.SalesPerson , count(*) AS Rank 
FROM tbl AS tbl1 INNER JOIN tbl AS tbl2 ON tbl1.DEPT = tbl2.DEPT 
    AND tbl1.#Customers < tbl2.#Customers 
GROUP BY tbl1.SalesPerson 
1

मैं जानता हूँ कि यह एक पुरानी धागा है। लेकिन चूंकि मैंने बहुत ही इसी तरह की समस्या पर काफी समय बिताया और यहां दिए गए पूर्व उत्तरों से बहुत मदद मिली, मैं जो कुछ भी पाया है उसे साझा करना चाहता हूं। (सावधान रहें, यह अधिक जटिल है।)

पहले "इंडिविलाइज़र" नामक एक और टेबल बनाएं। इसमें एक फ़ील्ड होगा जिसमें उच्चतम रैंक-आप-आवश्यकता के माध्यम से नंबर 1 की एक सूची होगी। Module1 के रूप में

'Global Declarations Section. 
Option Explicit 
Global Cntr 

'************************************************************* 
' Function: Qcntr() 
' 
' Purpose: This function will increment and return a dynamic 
' counter. This function should be called from a query. 
'************************************************************* 

Function QCntr(x) As Long 
    Cntr = Cntr + 1 
    QCntr = Cntr 
End Function 

'************************************************************** 
' Function: SetToZero() 
' 
' Purpose: This function will reset the global Cntr to 0. This 
' function should be called each time before running a query 
' containing the Qcntr() function. 
'************************************************************** 

Function SetToZero() 
    Cntr = 0 
End Function 

यह सहेजें:

अगला एक VBA मॉड्यूल बनाने और इसे पेस्ट करें।

इसके बाद, इस तरह QUERY1 बनाएँ:

SELECT Table1.Dept, Count(Table1.Salesperson) AS CountOfSalesperson 
FROM Table1 
GROUP BY Table1.Dept; 

एक MakeTable क्वेरी इस तरह QUERY2 बुलाया बनाएँ:

SELECT SetToZero() AS Expr1, QCntr([Identifier]) AS Rank, 
[Salesperson] & [Dept] & [#Customers] AS Identifier, Table1.Salesperson, 
Table1.Dept, Table1.[#Customers] 
INTO Qtable2 
FROM Table1; 

:

SELECT SetToZero() AS Expr1, QCntr([ID]) AS Rank, Query1.Dept, 
Query1.CountOfSalesperson, Individualizer.ID 
INTO Qtable1 
FROM Query1 
INNER JOIN Individualizer 
    ON Query1.CountOfSalesperson >= Individualizer.ID; 

एक और MakeTable क्वेरी इस तरह QUERY3 बनाएं जिसका नाम यदि आपके पास पहले से एक और क्षेत्र है जो विशिष्ट रूप से प्रत्येक पंक्ति को पहचानता है जिसे आपको बनाने की आवश्यकता नहीं होती है एन पहचानकर्ता क्षेत्र।

टेबल बनाने के लिए क्वेरी 2 और क्वेरी 3 चलाएं। इस तरह QUERY4 कहा जाता है एक चौथाई क्वेरी बनाएँ:

SELECT Qtable2.Salesperson, Qtable2.Dept, Qtable2.[#Customers], Qtable1.ID AS Rank 
FROM Qtable1 
INNER JOIN Qtable2 ON Qtable1.Rank = Qtable2.Rank; 

QUERY4 परिणाम आप देख रहे हैं देता है।

प्रैक्टिकल रूप से, आप क्वेरी 2 और क्वेरी 3 चलाने के लिए एक वीबीए फ़ंक्शन लिखना चाहते हैं और फिर उस फ़ंक्शन को सुविधाजनक स्थान पर रखे बटन से कॉल करना चाहते हैं।

अब मुझे पता है कि आपके द्वारा दिए गए उदाहरण के लिए यह हास्यास्पद रूप से जटिल लगता है। लेकिन वास्तविक जीवन में, मुझे यकीन है कि आपकी तालिका इससे अधिक जटिल है। उम्मीद है कि मेरे उदाहरण आपकी वास्तविक स्थिति पर लागू हो सकते हैं।12,000 से अधिक रिकॉर्ड वाले मेरे डेटाबेस में यह विधि एफएआर द्वारा सबसे तेज़ है (जैसा कि: 6 सेकंड के साथ 12 सेकंड रिकॉर्ड के साथ 6 सेकंड रिकॉर्ड के साथ 262 रिकॉर्ड सबक्वायरी विधि के साथ क्रमबद्ध हैं)।

मेरे लिए असली रहस्य मेकटेबल क्वेरी थी क्योंकि यह रैंकिंग विधि बेकार है जब तक कि आप तुरंत परिणामों को तालिका में आउटपुट न करें। लेकिन, यह उन परिस्थितियों को सीमित करता है जिन्हें इसे लागू किया जा सकता है।

पीएस मैं यह उल्लेख करना भूल गया कि मेरे डेटाबेस में मैं सीधे तालिका से परिणाम खींच नहीं रहा था। रिकॉर्ड्स की आवश्यकता होने से पहले रिकॉर्ड पहले से ही प्रश्नों और एकाधिक गणनाओं के माध्यम से चले गए थे। यह शायद मेरी स्थिति में दो तरीकों के बीच गति में भारी अंतर के लिए बहुत योगदान दिया। यदि आप सीधे किसी तालिका से रिकॉर्ड खींच रहे हैं, तो हो सकता है कि आप लगभग एक बड़ा सुधार न करें।

+0

योगदान के लिए धन्यवाद। रिकॉर्ड के लिए, जिसे आपने "इंडिविलाइज़र" कहा है, को आमतौर पर [संख्या तालिका] के रूप में जाना जाता है (http://www.mnscug.org/blogs/number-2/242-2-sql-tips-a-numbers- तालिका)। –

+0

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

0

मैं आम तौर पर यहां से युक्तियां और विचार चुनता हूं और कभी-कभी इससे अद्भुत चीजों का निर्माण समाप्त करता हूं!

आज, (अच्छी तरह से पिछले एक सप्ताह के लिए कहें), मैं एक्सेस में डेटा की रैंकिंग और मेरी योग्यता के साथ टंकण कर रहा हूं, मुझे उम्मीद नहीं थी कि मैं कुछ इतना जटिल करने जा रहा था इसे समझने के लिए मुझे एक सप्ताह ले लो! के रूप में जटिल विधि का विरोध करने के

  1. https://usefulgyaan.wordpress.com/2013/04/23/ranking-in-ms-access/ (देखा कि चतुर '> =' हिस्सा है, और आत्म मिलती कमाल ... यह मुझे मदद की सिर्फ एक क्वेरी से मेरी समाधान का निर्माण करने,: मैं दो मुख्य साइटों से titbits उठाया? उपरोक्त सुझाव दिया गया है (आपको अस्वीकार नहीं कर रहा है ... बस इसे अभी नहीं करना चाहता था; जब मैं बड़ा डेटा प्राप्त कर सकता हूं तो मैं इसे भी आजमा सकता हूं ...)
  2. यहां पर पॉल एबॉट से ऊपर (' और tbl.dept = tbl2.dept ') ... मैं रैंकिंग के बाद खो गया था क्योंकि मैं रख रहा था और वर्ष 1 = आदि, तो रैंकिंग केवल उप-सेट के लिए हो रही है, आपने सही अनुमान लगाया है, जब वर्ष 1 =! मेरे पास कई अलग-अलग परिदृश्य थे ...

ठीक है, मैंने आंशिक रूप से योगदानकर्ताओं का धन्यवाद करने के लिए यह कहानी दी है, क्योंकि मैंने जो किया वह रैंकिंग के सबसे जटिल में से एक है जो मुझे लगता है कि लगभग किसी भी स्थिति में आपकी मदद कर सकता है, और जब से मैं दूसरों से लाभान्वित हूं, मैं यहां साझा करना चाहता हूं जो मुझे उम्मीद है कि दूसरों को भी फायदा हो सकता है।

मुझे माफ़ कर दो कि मैं अपनी टेबल संरचनाओं को यहां पोस्ट करने में सक्षम नहीं हूं, यह बहुत से संबंधित तालिकाओं है। मैं केवल क्वेरी पोस्ट करूंगा, इसलिए यदि आपको आवश्यकता है तो आपको अपनी तरह की क्वेरी के साथ समाप्त करने के लिए अपनी टेबल विकसित कर सकते हैं। लेकिन यहां मेरा परिदृश्य है:

आपके पास स्कूल में छात्र हैं। वे कक्षा 1 से 4 तक जाते हैं, या तो स्ट्रीम ए या बी में हो सकते हैं, या कोई भी वर्ग बहुत छोटा होने पर नहीं हो सकता है। वे प्रत्येक 4 परीक्षाएं लेते हैं (यह हिस्सा अब महत्वपूर्ण नहीं है), इसलिए आपको मेरे मामले के लिए कुल स्कोर मिलता है। बस। हुह ??

ठीक है।

हम

सभी छात्रों को कभी इस स्कूल के माध्यम से पारित जो • की रैंकिंग में जानना चाहते हैं (सबसे अच्छा कभी छात्र)

एक विशेष शैक्षणिक वर्ष के सभी छात्रों • (के छात्र: उन्हें इस तरह से रैंक की सुविधा देता है वर्ष)

• किसी विशेष वर्ग के छात्र (लेकिन याद रखें कि एक छात्र सभी कक्षाओं के माध्यम से पारित हो जाएगा, इसलिए मूल रूप से अलग-अलग वर्षों के लिए उन वर्गों में से प्रत्येक में उनकी रैंक) यह सामान्य रैंकिंग है जो रिपोर्ट में दिखाई देती है कार्ड

अपनी स्ट्रीम में

• छात्रों (टिप्पणी लागू होता है ऊपर)

• मैं भी जनसंख्या जिसके खिलाफ हम प्रत्येक श्रेणी

में इस छात्र स्थान पर रहीं जानना चाहते हैं ... एक मेज/क्वेरी में सभी। अब आप बिंदु प्राप्त करते हैं?

(मुझे आमतौर पर मुझे संदेश देने के लिए डेटाबेस/प्रश्नों में से अधिकतर 'प्रोग्रामिंग' करना पसंद है और कोड की मात्रा को कम करने के लिए मुझे बाद में सही करना होगा। मैं वास्तव में इस क्वेरी का उपयोग नहीं करूँगा आवेदन :), लेकिन यह मुझे पता है कि कहाँ और कैसे क्वेरी यह से आया करने के लिए अपने मानकों को भेजने के लिए, और क्या परिणाम मेरे RDLC में की उम्मीद करने)

आप चिंता है, यहाँ यह है मत करो:

SELECT Sc.StudentID, Sc.StudentName, Sc.Mark, 
(SELECT COUNT(Sch.Mark) FROM [StudentScoreRankTermQ] AS Sch WHERE (Sch.Mark >= Sc.Mark)) AS SchoolRank, 
(SELECT Count(s.StudentID) FROM StudentScoreRankTermQ AS s) As SchoolTotal, 
(SELECT COUNT(Yr.Mark) FROM [StudentScoreRankTermQ] AS Yr WHERE (Yr.Mark >= Sc.Mark) AND (Yr.YearID = Sc.YearID)) AS YearRank, 
(SELECT COUNT(StudentID) FROM StudentScoreRankTermQ AS Yt WHERE (Yt.YearID = Sc.YearID)) AS YearTotal, 
(SELECT COUNT(Cl.Mark) FROM [StudentScoreRankTermQ] AS Cl WHERE (Cl.Mark >= Sc.Mark) AND (Cl.YearID = Sc.YearID) AND (Cl.TermID = Sc.TermID) AND (Cl.ClassID=Sc.ClassID)) AS ClassRank, 
(SELECT COUNT(StudentID) FROM StudentScoreRankTermQ AS C WHERE (C.YearID = Sc.YearID) AND (C.TermID = Sc.TermID) AND (C.ClassID = Sc.ClassID)) AS ClassTotal, 
(SELECT COUNT(Str.Mark) FROM [StudentScoreRankTermQ] AS Str WHERE (Str.Mark >= Sc.Mark) AND (Str.YearID = Sc.YearID) AND (Str.TermID = Sc.TermID) AND (Str.ClassID=Sc.ClassID) AND (Str.StreamID = Sc.StreamID)) AS StreamRank, 
(SELECT COUNT(StudentID) FROM StudentScoreRankTermQ AS St WHERE (St.YearID = Sc.YearID) AND (St.TermID = Sc.TermID) AND (St.ClassID = Sc.ClassID) AND (St.StreamID = Sc.StreamID)) AS StreamTotal, 
Sc.CalendarYear, Sc.Term, Sc.ClassNo, Sc.Stream, Sc.StreamID, Sc.YearID, Sc.TermID, Sc.ClassID 
FROM StudentScoreRankTermQ AS Sc 
ORDER BY Sc.Mark DESC; 

आपको ऐसा कुछ प्राप्त करना चाहिए:

छात्र आईडी | StudentName | मार्क | SchoolRank | SchoolTotal | YearRank | YearTotal | ClassRank | ClassTotal | StreamRank | StreamTotal | वर्ष | टर्म | कक्षा | स्ट्रीम

1 | जेन | 200 | 1 | 20 | 2 | 12 | 1 | 9 | 1 | 5 | 2017 | I | 2 | ए

2 | टॉम | 199 | 2 | 20 | 1 | 12 | 3 | 9 | 1 | 4 | 2016 | मैं | 1 | बी

उपयोग विभाजक (|) तालिकाओं के बारे में परिणाम तालिका

बस एक विचार फिर से संगठित करने, प्रत्येक छात्र को एक वर्ग से संबंधित कर दिया जाएगा। प्रत्येक वर्ग वर्षों से संबंधित है। प्रत्येक धारा एक वर्ग से संबंधित है। प्रत्येक शब्द एक वर्ष से संबंधित है। प्रत्येक परीक्षा एक शब्द और छात्र और एक वर्ग और एक वर्ष से संबंधित है; एक छात्र 2016 में कक्षा 1 ए में हो सकता है और 2017 में कक्षा 2 बी तक चला सकता है ...

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

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