2012-03-29 14 views
5

मुझे एक MySQL कथन की आवश्यकता है जो सभी पंक्तियों का चयन करेगी, साथ ही साथ कुल पंक्तियां कितनी हैं।MySQL अतिरिक्त पंक्तियों के रूप में पंक्तियों की गिनती का चयन करना?

मैं

mysql_query("SELECT * FROM posts LIMIT 0, 5"); 

उपयोग कर रहा था ... गिनती जोड़ने की कोशिश कर:

mysql_query("SELECT *, COUNT(*) AS total FROM posts LIMIT 0, 5"); 

... लेकिन यह है कि केवल एक ही पंक्ति देता है।

इसके अलावा, यदि प्रत्येक पंक्ति में अतिरिक्त कॉलम जोड़ने के लिए कुल मिलाकर बेहतर तरीका है, तो मुझे इसके बजाय यह पसंद आएगा। धन्यवाद!

+2

यदि आप PHP का उपयोग कर रहे हैं, तो क्यों नहीं 'mysql_num_rows' – hjpotter92

+1

@ hjpotter92 का उपयोग करें, लेकिन यह इस पर निर्भर करता है कि "कुल" ओपी सोच रहा है। वर्तमान में चयनित कुल ('mysql_num_rows' से ठीक है) या पूरी तालिका में पंक्तियों की संख्या। –

+0

अच्छा बिंदु, @ मिचल। मैंने अपने जवाब में दोनों मामलों को संबोधित किया। –

उत्तर

9

मैं ने MySQL बयान है कि सभी पंक्तियों का चयन करेंगे, साथ ही कितने कुल पंक्तियों को देखते हैं की जरूरत है।

जब शाब्दिक रूप से लिया गया, तो यह संभव नहीं है। एक SQL क्वेरी का परिणाम एक (आभासी) तालिका है; उस परिणाम तालिका में प्रत्येक पंक्ति में स्तंभ केवल उस पंक्ति से जुड़ा एक मान प्रदान करता है, और पंक्तियां एक दूसरे से स्वतंत्र होती हैं।

पूरे परिणाम की पंक्ति गणना को पकड़ने के कई तरीके हैं, लेकिन यह या तो दो कथन में किया गया है या एक क्वेरी के साथ जो आपके पास है उससे अवधारणात्मक रूप से अलग है। (नीचे सॉल्यूशंस)

अपने मूल प्रश्न में एक पहलू यह है कि कई मायनों में व्याख्या की जा सकती है:

के साथ ही कितने कुल पंक्तियों को देखते

यानी हो सकता है या तो कर रहे हैं:

  1. परिणाम में लौटाई गई प्रत्येक पंक्ति की गणना करें।
  2. प्रत्येक पंक्ति है कि अगर यह सीमा खंड (जो इस मामले में 5 पंक्तियों को परिणाम ट्रंकेटस)

(मैं दोनों नीचे के लिए उत्तर प्रदान करेंगे) के लिए नहीं थे लौटा दिए गए हैं गणना

लेकिन यह केवल एक पंक्ति देता है। मैं अनुमान लगा रहा हूं क्योंकि COUNT (*) प्रत्येक पंक्ति के लिए समान होगा, और किसी कारण से, MySQL केवल इसके लिए अद्वितीय मानों वाली पंक्तियों को वापस कर रहा है? मेरे पास कोई सुराग नहीं है।

COUNT एक समग्र कार्य है। एक समग्र फ़ंक्शन का उपयोग करके, आप डेटाबेस को पंक्तियों के समूह को घुमाने और एक पंक्ति में इसके कुछ पहलुओं को प्रोजेक्ट करने के लिए कह रहे हैं। भ्रमित करने वाला यह है कि MySQL भी आपको SELECT सूची में गैर-कुल और कुल अभिव्यक्तियों को मिश्रण करने के लिए है। अधिकांश अन्य डेटाबेस इस की अनुमति नहीं देते हैं और इसके लिए आपको एक त्रुटि देते हैं, लेकिन हां MySQL नहीं करता है।

लेकिन COUNT (*) अभी भी सभी पंक्तियों को एक पंक्ति में जोड़ता है, जो पंक्तियों के पूरे समूह का प्रतिनिधित्व करता है।

इसके अलावा, यदि प्रत्येक पंक्ति में अतिरिक्त कॉलम जोड़ने के लिए कुल मिलाकर बेहतर तरीका है, तो मुझे इसके बजाय यह पसंद आएगा। धन्यवाद!

हाँ, कई तरीके हैं।

आप पंक्तियों की संख्या प्राप्त करना चाहते हैं पीएचपी में लौट आए, इसलिए, MySQL अपनी सीमा खंड लागू किया के बाद, मैं बस php समारोह mysql_num_rows (http://www.php.net/manual/en/function.mysql-num-rows.php) mysql_query कॉल करने के बाद फोन करने का सुझाव देते हैं।

यदि आप LIMIT खंड की अनुपस्थिति में लौटाई गई पंक्तियों की संख्या प्राप्त करना चाहते हैं, तो मैं इसे 2 चरणों में करने का सुझाव देता हूं: सबसे पहले, अपनी मूल क्वेरी के एक छोटे से संशोधित संस्करण को निष्पादित करें, और फिर तत्काल बाद कि, MySQL के FOUND_ROWS फ़ंक्शन को कॉल करें। (http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_found-rows देखें)

यह इस तरह दिखेगा:

$result = mysql_query('SELECT SQL_CALC_FOUND_ROWS * FROM posts LIMIT 0, 5'); 
//do stuff with the result, but don't do any other queries 

//get the total number of rows (disregarding the LIMIT clause) 
$result = mysql_query('SELECT FOUND_ROWS()'); 

SQL_CALC_FOUND_ROWS संशोधक MySQL बताता LIMIT खंड लागू करने से पहले पंक्तियों की कुल संख्या का ट्रैक रखने के लिए, और FOUND_ROWS() रिटर्न उस नंबर। मन में 2 बातें रखें:

  1. इन दोनों mysql_query कॉल एक ही कनेक्शन
  2. mysql_query

ओह, अंतिम नोट करने के लिए इन कॉल inbetween किसी अन्य क्वेरी को निष्पादित न करें अधिक निष्पादित किया जाना चाहिए: का उपयोग करते समय LIMIT, आप आम तौर पर परिणामों को किसी विशेष तरीके से आदेश देना चाहते हैं। आमतौर पर लोग अंकन के लिए LIMIT का उपयोग करते हैं। यदि आप पंक्तियों का ऑर्डर नहीं करते हैं, तो ऑर्डर अनिश्चित है और बाद के प्रश्न पिछले बयान द्वारा पहले से लौटाई गई पंक्तियों को वापस कर सकते हैं, भले ही LIMIT ऑफ़सेट अलग हो। आप ORDER BY खंड का उपयोग कर परिणाम को स्पष्ट रूप से ऑर्डर कर सकते हैं। (http://dev.mysql.com/doc/refman/5.5/en/select.html)

+0

हां, मैं आपके आखिरी वक्तव्य पर पूरी तरह से सहमत हूं, वास्तव में 'ऑर्डर बीई' क्लॉज का उपयोग कर परिणाम सेट को ऑर्डर करना संभव है। असल में, मैं कहां तक ​​कहूंगा, "** केवल ** 'ऑर्डर बाय' क्लॉज का उपयोग करके। ;) बस थोड़ा सा व्यंग्यात्मक, क्षमा करें। मुझे आपका जवाब अच्छी तरह से विस्तृत और शिक्षित, +1 मिलता है। –

+1

+1 'FOUND_ROWS() ' –

+0

@Andriy हे, धन्यवाद :) बस एक नाइटपिक, लेकिन MySQL में, बेहतर या बदतर के लिए, ग्रुप बाय क्लॉज को ऑर्डर किए गए परिणाम को वापस करने की भी गारंटी दी जाती है। आप ग्रुप बाय सूची में अभिव्यक्तियों के लिए एएससी और डीईएससी संशोधक भी निर्दिष्ट कर सकते हैं। –

8

मुझे यकीन नहीं है कि आप किस बारे में सोच रहे हैं: कुल वर्तमान में चयनित या पूरी तालिका में सभी पंक्तियों की संख्या। यह प्रत्येक पंक्ति में एक ही मूल्य में पूरे तालिका में सभी पंक्तियों की संख्या देता है, निश्चित रूप से:

mysql_query("SELECT *, (select COUNT(*) from posts) AS total FROM posts LIMIT 0, 5"); 
+0

ठीक है, धन्यवाद, यह सही है। मुझे लगता है कि मैं उस अन्य क्वेरी को केवल उस क्वेरी की गणना करने के लिए संशोधित कर सकता हूं जो मैं चाहता हूं। क्या यह बहुत अक्षम है? क्या यह कई बार पूछताछ कर रहा है? – mowwwalker

+0

@ वाल्केर्नियो यदि यह आपका वास्तविक प्रश्न है, तो mysql_num_rows सबसे अच्छा समाधान है। – hjpotter92

+0

@ वाल्केर्नियो यह सहसंबंधित नहीं है (बाहरी और आंतरिक क्वेरी के बीच कोई सहसंबंध नहीं है) इसलिए इसे दक्षता खोना नहीं चाहिए। और हाँ आप आंतरिक क्वेरी को अपनी इच्छित चीज़ों तक सीमित कर सकते हैं। –

1

मुझे लगता है कि आप इस मुद्दे को अधिक जटिल बना रहे हैं। मुझे दो प्रश्नों का उपयोग करने में कोई समस्या नहीं दिख रही है।

SELECT COUNT(*) AS total FROM posts; 

और एक दूसरे, अपने पदों के लिए क्वेरी करने के लिए:

SELECT * FROM posts LIMIT 0, 5 

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

यदि आप इसे सबक्वायरी का उपयोग करके अतिरिक्त कॉलम के रूप में जोड़ना चाहते हैं, तो आपके पास प्रत्येक पंक्ति में कुल होगा, लेकिन आप मूल रूप से दो प्रश्नों को चला रहे होंगे (या प्रत्येक पंक्ति के लिए सबक्वायरी रन I याद नहीं कर सकते?)

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

उदाहरण के लिए कई प्रश्नों के मामले में, कहें कि आप पोस्ट और टिप्पणियां प्राप्त करना चाहते हैं, तो आपको गलत गिनती मिल जाएगी क्योंकि पोस्ट उस पोस्ट के लिए प्रत्येक टिप्पणी के लिए डुप्लीकेट हो जाएगा।

संक्षिप्त उदाहरण:

post_id | comment_id 
1  | 1 
1  | 2 
2  | 3 
3  | 4 
3  | 5 

तो इसे सही ढंग से करने के लिए आपको सबसे पहले कुल पदों प्राप्त करने के लिए निम्न क्वेरी को चलाने के लिए आवश्यकता होगी:

SELECT COUNT(*) AS total FROM posts; 

और फिर आप को चलाने के लिए आवश्यकता होगी:

SELECT id FROM posts limit 0, 5; 

और अंत में आप चलाने चाहते हैं:

select p.id, c.id from posts p left join comments c on c.post_id = p.id where id in(id list from above query) 

स्पष्ट रूप से आपकी क्वेरी उपरोक्त समस्या में नहीं चलेगी। लेकिन मैं बस यह बताने की कोशिश कर रहा हूं कि एक अलग क्वेरी में कुल गिनती क्यों प्राप्त हो सकती है।

+1

एकाधिक प्रश्नों का उपयोग करने के लिए हालांकि, समवर्तीता के बारे में सोचने की आवश्यकता होती है। क्या होगा यदि आपकी पहली क्वेरी खत्म होने के बाद कुछ पंक्तियां जोड़ती या निकालती है, लेकिन दूसरे से पहले शुरू होता है? दूसरी क्वेरी द्वारा लौटाई गई गिनती पहले के परिणामों के साथ असंगत होगी।(आप एक बहुत ही अलग अलगाव स्तर के साथ एक ही लेनदेन में दोनों प्रश्नों से ऐसा कर सकते हैं।) – Wyzard

+0

हां, लेनदेन में प्रश्नों को चलाने के बारे में अच्छा बिंदु। – Gohn67

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