2012-03-10 8 views
6

मेरे तालिका है-कॉलम के औसत की गणना कैसे करें और फिर इसे ऑरैकल में एक चुनिंदा क्वेरी में शामिल करें?

create table mobile 
(
    id integer, 
    m_name varchar(20), 
    cost integer 
) 

और मूल्यों कर रहे हैं -

insert into mobile values(10,'NOkia',100); 
insert into mobile values(11,'Samsung',150); 
insert into mobile values(12,'Sony',120); 

मुझे पता है कि स्तंभ लागत पर औसत की गणना करने के लिए, मेरे कोड है-

select avg(cost) from mobile; 

और नतीजा

लेकिन iw चींटी औसत की गणना करने के लिए और फिर यह भी पता चलता फर्क यह करने में सक्षम था, लेकिन, मैं चयन query--

मेरे कोड है में औसत स्तंभ जोड़ने के लिए सक्षम नहीं हूँ ---

SELECT id, m_name as "Mobile Name", cost as Price,avg(cost) as Average, 
cost-(select avg(cost) from mobile) as Difference FROM mobile 
group by id,m_name,cost; 

और उत्पादन होता है -

id  Mobile Name Price Average Difference 
10  Nokia   100 100  -23 
11  Samsung  150 150  27 
12  Sony   120 120  -3 

है कि मैं क्या चाहता है यह औसत स्तंभ को दूर करने के लिए है .. मैं इस चाहता है ---

id  Mobile Name Price Average Difference 
10  Nokia  100  123  -23 
11  Samsung  150  123  27 
12  Sony  120  123  -3 

कृपया मदद ...

+3

+1 'तालिका बनाएं' और नमूना डेटा को 'डालने' के रूप में आपूर्ति करने के लिए +1, लेकिन यह ओरेकल वाक्यविन्यास मान्य नहीं है (ओरेकल में 'bigint' या 'int नहीं है)। और संख्याओं को एकल उद्धरण में नहीं रखा जाना चाहिए! –

+1

@ जस्टिन पिहनी, आप इसके बजाय '[faq]', [faq], '[ask]', [ask] आदि का उपयोग कर सकते हैं, http://stackoverflow.com/editing-help#comment-formatting – Ben

+0

@Ben धन्यवाद, मैं टिप्पणी स्वरूपण देखने के लिए मतलब रहा है। बहुत सराहना की। –

उत्तर

9

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

SELECT id, m_name AS "Mobile Name", cost AS Price, 
    (SELECT AVG(cost) FROM mobile) AS Average, 
    cost-(SELECT AVG(cost) FROM mobile) AS Difference 
FROM mobile; 

जब आप बुनियादी SELECT AVG(cost) बयान यह स्वाभाविक रूप से कॉलम निर्धारित (इस मामले में लागत) है कि के रूप में द्वारा समूहीकरण है चलाने के तुम क्या अनुरोध कर रहे हैं है। मैं अवधारणा पर बेहतर समझ पाने के लिए GROUP BY और aggregates पर और अधिक पढ़ने का सुझाव दूंगा। इससे आपको एक साधारण समाधान से अधिक मदद मिलनी चाहिए।

अद्यतन:

जवाब नीचे डेविड के जवाब से वास्तव में है। यह विश्लेषणात्मक कार्यों का उपयोग करता है। असल में, क्या हो रहा है कि प्रत्येक एवीजी कॉल पर, आप इंजन को बता रहे हैं कि फ़ंक्शन के लिए क्या उपयोग करना है (इस मामले में, कुछ भी नहीं)। विश्लेषणात्मक कार्यों पर एक सभ्य लेखन here और here और इस मामले पर Google के साथ और अधिक पाया जा सकता है।

SELECT id, m_name AS "Mobile Name" cost AS Price, AVG(cost) OVER() AS Average, 
    cost - AVG(cost) OVER () AS Difference 
    FROM mobile 

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

इसके अलावा, यह समाधान दो बार एक ही क्वेरी को डुप्लिकेट करता है, इसलिए यह SQL चर में आपके औसत को संग्रहीत करने के लायक हो सकता है। तो फिर तुम बस का उपयोग करने के अपने बयान बदलने ca कि वैश्विक औसत

यह एसक्यूएल-सर्वर में चर

DECLARE @my_avg INT; 
SELECT @my_avg = AVG(cost) FROM Mobile; 

    SELECT id, m_name AS "Mobile Name", cost AS Price, 
     @my_avg AS Average, [email protected]_avg AS Difference 
    FROM mobile; 

यह समाधान एक बहुत दिखाया जाएगा (आप एसक्यूएल का अपना स्वयं का उदाहरण के लिए यह अनुकूल करने के लिए होगा) है अपने एसक्यूएल के भविष्य के पाठकों के लिए क्लीनर भी

+0

मुझे पूरा यकीन है कि डेविड की क्वेरी कम से कम कुशल है और उसे पीएल/एसक्यूएल ब्लॉक के उपयोग की आवश्यकता नहीं है, जिसके लिए आपको चयन का परिणाम वैरिएबल में डालना होगा - यह आपके द्वारा लिखे गए तरीके से प्रदर्शित नहीं होगा (वास्तव में मुझे लगता है कि यह भी नहीं चलेंगे)। और डुप्लीकेट क्वेरी के अलावा ओरेकल द्वारा केवल एक बार चलाया जाएगा। मुझे पूरा यकीन है कि ऑप्टिमाइज़र उसको पहचानने के लिए पर्याप्त स्मार्ट है। –

+0

मैं आपकी व्याख्या की सराहना करता हूं, लेकिन पीएल/एसक्यूएल ब्लॉक बस गलत है। वह दृष्टिकोण ओरेकल में कभी काम नहीं करेगा। यदि आप औसत() क्वेरी दोहराना नहीं चाहते हैं, तो विश्लेषणात्मक फ़ंक्शन या क्रॉस जॉइन समाधान के साथ दृष्टिकोण का उपयोग करें। –

+0

यह पीएल/एसक्यूएल सही नहीं बनाता है। यह अभी भी * गलत * है और ** ** –

0

SELECT id, m_name as "Mobile Name", cost as Price,(select avg(cost) from mobile) as Average), 
cost-(select avg(cost) from mobile) as Difference FROM mobile 
group by id,m_name,cost; 

अगर आपकी क्वेरी काफी महंगी है कि जिस तरह से मुझे एक सराहना छोड़ तो मैं इसे सुधार होगा की कोशिश करो।

2

सबसे आसान परिवर्तन avg(cost) as Average को (select avg(cost) from mobile) as Average में बदलना है। यह भी मतलब है कि आप (क्योंकि यह क्या आप वास्तव में चाहते थे नहीं है) अब और GROUP BY खंड की जरूरत नहीं होगी:

SELECT id, 
     m_name AS "Mobile Name", 
     cost AS "Price", 
     (SELECT AVG(cost) FROM mobile) AS "Average", 
     cost - (SELECT AVG(cost) FROM mobile) AS "Difference" 
    FROM mobile 
; 
0

ऐसे दुर्लभ अवसरों में से एक एक CROSS JOIN लागू होता है:

WITH avgcost as (select round(avg(cost)) as Average from mobile) 
SELECT id, m_name as "Mobile Name", cost as Price, Average, 
cost-Average as Difference 
FROM mobile cross join avgcost 

कौन सा में परिणाम होगा:

ID Mobile Name PRICE AVERAGE DIFFERENCE 
10 NOkia  100  123  -23 
11 Samsung  150  123  27 
12 Sony  120  123  -3 
11

आप ओरेकल का उपयोग कर रहे हैं, इसलिए आपको एक विश्लेषणात्मक (विंडो) के रूप में उपयोग करने के लिए औसत() सक्षम होना चाहिए समारोह:

SELECT id, m_name AS "Mobile Name" cost AS Price, AVG(cost) OVER() AS Average 
    , cost - AVG(cost) OVER () AS Difference 
    FROM mobile 

सबक्वेरी ऑर ग्रुप के लिए कोई ज़रूरत नहीं।

+1

+ विश्लेषणात्मक समारोह का 1 अच्छा उपयोग :) –

0
select pid, name, price as actualcost, 
     AVERAGE = (select AVG(price) from Part_Master), 
     price - (select AVG(price) as diff from Part_Master) AS COST_DIFF 
from Part_Master 
संबंधित मुद्दे