Quassnoi के जवाब से पता चलता SUMPRODUCT कैसे करना है, और कहां खंड आप एक दिनांक फ़ील्ड से प्रतिबंधित करने की अनुमति होगी एक का उपयोग कर ...
SELECT
SUM([tbl].data * [tbl].weight)/SUM([tbl].weight)
FROM
[tbl]
WHERE
[tbl].date >= '2009 Jan 01'
AND [tbl].date < '2010 Jan 01'
अधिक जटिल हिस्सा वह जगह है जहां आप "गतिशील रूप से निर्दिष्ट" करना चाहते हैं कि कौन सा क्षेत्र [डेटा] है और [फ़ील्ड] क्या फ़ील्ड है। संक्षिप्त जवाब यह है कि वास्तव में आपको गतिशील एसक्यूएल का उपयोग करना होगा। की तर्ज पर कुछ:
- बनाएँ एक स्ट्रिंग टेम्पलेट
- उपयुक्त डेटा क्षेत्र
साथ .data की [tbl] सब बदल दें - [tbl] उचित वजन क्षेत्र
साथ .weight के सभी उदाहरणों बदलें - स्ट्रिंग
डायनामिक एसक्यूएल निष्पादित करें, हालांकि, इसका अपना ओवरहेड होता है। क्या प्रश्न अपेक्षाकृत कम हैं, या क्वेरी का निष्पादन समय अपेक्षाकृत लंबा है, इससे कोई फर्क नहीं पड़ता। यदि वे आम और छोटे हैं, हालांकि, आप देख सकते हैं कि गतिशील एसक्यूएल का उपयोग करके एक उल्लेखनीय ओवरहेड पेश किया जाता है। (नहीं एसक्यूएल इंजेक्शन हमलों से सावधान किया जा रहा है उल्लेख करने के लिए, आदि)
संपादित करें:
अपने नवीनतम उदाहरण में आप तीन क्षेत्रों पर प्रकाश डाला:
जब [केपीआई] "वजन वाई ", फिर [वास्तविक] उपयोग करने के लिए वज़न फैक्टर।
जब [केपीआई] "टोंस मिल्ड" होता है, तो [वास्तविक] वह डेटा होता है जिसे आप एकत्र करना चाहते हैं।
कुछ सवाल मेरे पास है कर रहे हैं:
- वहाँ किसी भी अन्य क्षेत्रों रहे हैं?
- क्या प्रति केपीआई प्रति दिन केवल एक वास्तविक वास्तविक है?
कारण मैं पूछता हूं कि आप यह सुनिश्चित करना चाहते हैं कि आप जो जॉइन करते हैं वह केवल 1: 1 है।(आप नहीं है 5 वास्तविक 5 बाट के साथ शामिल होने 25 resultsing रिकॉर्ड देने चाहते हैं,)
परवाह किए बिना, आपकी क्वेरी के एक मामूली सरलीकरण निश्चित रूप से संभव है ...
SELECT
SUM([baseSeries].Actual * [weightSeries].Actual)/SUM([weightSeries].Actual)
FROM
CalcProductionRecords AS [baseSeries]
INNER JOIN
CalcProductionRecords AS [weightSeries]
ON [weightSeries].RecordDate = [baseSeries].RecordDate
-- AND [weightSeries].someOtherID = [baseSeries].someOtherID
WHERE
[baseSeries].KPI = 'Tons Milled'
AND [weightSeries].KPI = 'Weighty'
लाइन पर टिप्पणी की केवल अगर जरूरत आपको अपने डेटा और वजन के बीच 1: 1 संबंध सुनिश्चित करने के लिए अतिरिक्त भविष्यवाणियों की आवश्यकता है।
आप तारीख प्रति सिर्फ एक मूल्य guarnatee नहीं कर सकते, और पर शामिल होने के लिए किसी भी अन्य क्षेत्रों की जरूरत नहीं है, तो आप अपने sub_query आधारित संस्करण से थोड़ा संशोधित कर सकते हैं ...
SELECT
SUM([baseSeries].Actual * [weightSeries].Actual)/SUM([weightSeries].Actual)
FROM
(
SELECT
RecordDate,
SUM(Actual)
FROM
CalcProductionRecords
WHERE
KPI = 'Tons Milled'
GROUP BY
RecordDate
)
AS [baseSeries]
INNER JOIN
(
SELECT
RecordDate,
AVG(Actual)
FROM
CalcProductionRecords
WHERE
KPI = 'Weighty'
GROUP BY
RecordDate
)
AS [weightSeries]
ON [weightSeries].RecordDate = [baseSeries].RecordDate
यह मानता है कि वज़न के एवीजी वैध हैं यदि उसी दिन कई वजन होते हैं।
संपादित करें: के लिए इस इसलिए मैंने सोचा कि मैं अंतिम जवाब :)
SELECT
SUM(Actual * Weight)/SUM(Weight)
FROM
(
SELECT
RecordDate,
SUM(CASE WHEN KPI = 'Tons Milled' THEN Actual ELSE NULL END) AS Actual,
AVG(CASE WHEN KPI = 'Weighty' THEN Actual ELSE NULL END) AS Weight
FROM
CalcProductionRecords
WHERE
KPI IN ('Tons Milled', 'Weighty')
GROUP BY
RecordDate
)
AS pivotAggregate
इस से बचा जाता है में शामिल हों और यह भी केवल तालिका एक बार स्कैन करता है में सुधार चाहते हैं किसी ने मतदान किया।
यह इस तथ्य पर निर्भर करता है किकी गणना करते समय NULL
मानों को अनदेखा किया जाता है।
कैसे तिथि सीमा में आता है की कोशिश? कितने कॉलम - कुछ या बहुत सारे? कॉलम की संख्या तय है? –
@ मार्टिन, सिर्फ एक कॉलम। यह प्रति केपीआई प्रति एक था, लेकिन यह मजेदार नहीं था। दिनांक सीमा एक रिपोर्टिंग अवधि के लिए है। – ProfK
क्या उपरोक्त कथन एक सीटीई माना जाता है? यदि नहीं, तो आप इसे सीटीई में कैसे बदल सकते हैं? किसी को? – PositiveGuy