2015-12-16 5 views
5

मेरा लक्ष्य सप्ताह के किसी दिए गए दिन और/या दिन के समय गेराज (वाई-अक्ष) की औसत अधिभोग दिखाते हुए एक रिपोर्ट उत्पन्न करना है।रिकॉर्ड्स के समूह पर समूहित औसत पर रिपोर्टिंग

  • गैराज has_many कारें और गैराज has_many नियुक्ति, through: :cars
  • कार has_many नियुक्ति
  • नियुक्ति जैसे क्षेत्रों है:
    • picked_up_at (दिनांक)
    • returned_at मेरे डेटा मॉडल इस प्रकार है (डेटाटाइम)

इसके अलावा, गेराज में capacity (integer) फ़ील्ड है, जो गेराज में फिट होने वाली कारों की अधिकतम संख्या है।

यदि मेरे पास पिछले 6 महीनों में फैली नियुक्तियों की एक सूची है, और मैं सप्ताह के प्रत्येक दिन दिखाए गए एक्स-अक्ष के साथ एक रेखा-ग्राफ उत्पन्न करना चाहता हूं, तो 4-घंटे अंतराल में टूटा हुआ है, और वाई -एक्सिस दिए गए दिन/घंटे अंतराल के लिए 6 महीने की अवधि में औसत% अधिभोग (गेराज/क्षमता में कारों का #) दिखा रहा है, मैं इस डेटा को रिपोर्ट करने के लिए कैसे एकत्र कर सकता हूं?

उदा। एक कार In नियुक्ति के पिकअप तक नियुक्ति की वापसी के समय से, और Out नियुक्ति के पिकअप से returned_at समय तक है।

मुझे इन डेटा बिंदुओं से कनेक्शन को अर्थपूर्ण रिपोर्ट करने और अंतिम उपयोगकर्ता को पेश करने का सबसे अच्छा तरीका बनाने में बहुत परेशानी हो रही है।

मैं रेल 4.1 और रूबी 2.0 का उपयोग कर रहा हूं।

संपादित करें: एसक्यूएल फिडल - http://sqlfiddle.com/#!9/a72fe/1

+0

आपका बेला MySQL के लिए है। आप अपने प्रश्न से मेल खाने के लिए पोस्टग्रेस में इसे बदलना चाहेंगे: http://sqlfiddle.com/#!15/77901/1। साथ ही, आपने 'return_at' में संभावित नल मानों का उल्लेख करने के लिए उपेक्षित किया (मैंने आपके कॉलम नामों से मेल खाने के लिए स्कीमा को भी अनुकूलित किया।) –

+0

तो क्या आपका उत्तर है? –

+0

@ErwinBrandstetter - एक उत्तर चुनने में देरी के लिए खेद है, मैं देश से बाहर हूं, लेकिन मैं आपके समाधान को लागू करने के लिए काम कर रहा हूं और जैसे ही मैं करता हूं, मैं जवाब स्वीकार करूंगा। धन्यवाद फिर से – jackerman09

उत्तर

4

इस क्वेरी यह सब करना होगा (अपने जोड़े गए बेला के लिए अनुकूलित):

SELECT a.ts, g.*, round((a.ct * numeric '100')/g.capacity, 2) AS pct 
FROM (
    SELECT ts, c.garage_id, count(*) AS ct 
    FROM generate_series(timestamp '2015-06-01 00:00' -- lower and 
         , timestamp '2015-12-01 00:00' -- upper bound of range 
         , interval '4h') ts 
    JOIN appointment a ON a.picked_up_at <= ts  -- incl. lower 
         AND (a.returned_at > ts OR 
          a.returned_at IS NULL) -- excl. upper bound 
    JOIN car c ON c.id = a.car_id 
    GROUP BY 1, 2 
    ) a 
JOIN garage g ON g.id = a.garage_id 
ORDER BY 1, 2; 

SQL Fiddle.

returned_at IS NULL हैं, तो इस क्वेरी मान लिया गया है कि कार अभी भी उपयोग में है। इसलिए अन्य मामलों के लिए न्यूल नहीं होना चाहिए या आपको गणना में कोई त्रुटि है।

सबसे पहले, मैं सुविधाजनक generate_series() फ़ंक्शन के साथ समय श्रृंखला का निर्माण करता हूं।

फिर उन नियुक्तियों में शामिल हों जहां बुकिंग के दौरान टाइमस्टैम्प गिरता है।
मैं व्यापक रूप से सम्मेलन के रूप में ऊपरी टाइमस्टैम्प को छोड़कर और नीचे सहित प्रत्येक नियुक्ति मानता हूं।

गैरेज में शामिल होने से पहले कुल मिलाकर गिनें (इस तरह तेज़ी से)। की तुलना करें: बाहरी SELECT में

प्रतिशत गणना।
मैं संख्या numeric (या वैकल्पिक रूप से real या float) के साथ गुणात्मक अंकों को संरक्षित करने के लिए गुणा करें, जो एक पूर्णांक विभाजन में काटा जाएगा। फिर मैं दो आंशिक अंकों के लिए गोल।

नोट कि यह प्रत्येक 4-घंटे की अवधि का औसत प्रतिशत नहीं है, लेकिन समय पर प्रत्येक बिंदु पर केवल वर्तमान प्रतिशत, जो वास्तविक औसत का अनुमान है। आप '2015-06-01 01:17' जैसे अजीब टाइमस्टैम्प से शुरू कर सकते हैं, इसलिए बुकिंग के बीच में न पड़ना जो शायद पूरे घंटों या किसी चीज़ पर चालू हो जाए, जो अनुमान के औसत त्रुटि को बढ़ा सकता है।

आप 4h अवधि के लिए भी सटीक गणना कर सकते हैं, लेकिन यह अधिक परिष्कृत है। एक साधारण तकनीक अंतराल को 10 मिनट या कुछ ग्रैन्युलरिटी को कम करने के लिए होगी जो पूर्ण तस्वीर को पकड़ने के लिए पर्याप्त विस्तृत है।

संबंधित (सटीक गणना के लिए एक उदाहरण के साथ):

+0

त्वरित और विस्तृत प्रतिक्रिया के लिए धन्यवाद! मैं इसकी समीक्षा/परीक्षण करूंगा और वापस रिपोर्ट करूंगा! – jackerman09

+0

जब मैं अपनी क्वेरी को अपनी पहेली में कॉपी करता हूं, तो मुझे यह त्रुटि मिलती है: 'आपको अपने SQL वाक्यविन्यास में कोई त्रुटि है; 'numeric' 100 'के निकट उपयोग करने के लिए सही वाक्यविन्यास के लिए आपके MySQL सर्वर संस्करण से मेल खाने वाले मैन्युअल की जांच करें)/g.capacity, 2) AS pct से (चयन टी, c.garage_id, गिनती (' लाइन 1' पर, चाहिए जिसने सीधे लिखा है, आपने लिखा है? – jackerman09

+0

@ जैकमेन 0 9: क्योंकि * आपका * फीड MySQL के लिए है (जो पोस्टग्रेज़ के लिए टैग किए गए एक प्रश्न के लिए बस गलत है)। * मेरी * पहेली, यह काम करता है। –

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