2016-05-07 11 views
8

वर्तमान में विकास में MySQL 5.7 और उत्पादन में 5.6 के साथ काम कर रहा हूं। प्रत्येक बार जब मैं विकास में समूह के साथ एक क्वेरी चलाता हूं तो मुझे कुछ त्रुटि मिलती है जैसे "त्रुटि कोड: 1055. SELECT सूची का अभिव्यक्ति # 1 ग्रुप में नहीं है"क्या mysql 5.6 के लिए ANY_VALUE क्षमता है?

यहां प्रश्न है।

SELECT c.id, c.name, i.* 
FROM countries c, images i 
WHERE i.country_id = c.id 
GROUP BY c.id; Fixed for 5.7; 

SELECT c.id, c.name, 
     ANY_VALUE(i.url) url, 
     ANY_VALUE(i.lat) lat, 
     ANY_VALUE(i.lng) lng 
    FROM countries c, images i 
WHERE i.country_id = c.id 
GROUP BY c.id; 

सुलझाने है कि मैं 5.7 ANY_VALUE से mysql फ़ंक्शन का उपयोग करें, लेकिन मुख्य मुद्दा यह है कि mysql में अपनी उपलब्ध नहीं है के लिए 5.6

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

क्या आप mysql 5.6 में ANY_VALUE फ़ंक्शन के लिए कोई समाधान या polifill जानते हैं?

+1

क्यों न केवल 'MIN' या' MAX' का उपयोग करें? – trincot

उत्तर

9

आप notorious nonstandard MySQL extension to GROUP BY का दुरुपयोग कर रहे हैं। मानक एसक्यूएल हमेशा आपकी क्वेरी को अस्वीकार कर देगा, क्योंकि आप कॉलम का उल्लेख कर रहे हैं जो समेकित नहीं हैं और GROUP BY में उल्लेख नहीं किया गया है।अपने देव तंत्र में आप ANY_VALUE() के साथ उस पर काम करने की कोशिश कर रहे हैं।

उत्पादन में, आप बंद कर सकते हैं ONLY_FULL_GROUP_BY MySQL Mode.this करने का प्रयास करें:

SET @mode := @@SESSION.sql_mode; 
    SET SESSION sql_mode = ''; 
    /* your query here */ 
    SET SESSION sql_mode = @mode; 

यह MySQL आपकी क्वेरी को स्वीकार करने की अनुमति देगा।

लेकिन देखो, आपकी क्वेरी वास्तव में सही नहीं है। जब आप इसे चलाने के लिए राजी कर सकते हैं, तो यह images तालिका से यादृच्छिक रूप से चुनी गई पंक्ति लौटाता है। इस प्रकार की अनिश्चितता अक्सर उपयोगकर्ताओं और आपके तकनीकी सहायता दल के लिए भ्रम पैदा करती है।

क्वेरी को बेहतर क्यों नहीं बनाते, इसलिए यह एक विशेष छवि चुनता है। यदि आपकी images तालिका में एक ऑटोइनक्रिकमेंट id कॉलम है तो आप "पहली" छवि का चयन करने के लिए ऐसा कर सकते हैं।

SELECT c.id, c.name, i.* 
    FROM countries c 
    LEFT JOIN (
     SELECT MIN(id) id, country_id 
     FROM images 
     GROUP BY country_id 
     ) first ON c.id = first.country_id 
    LEFT JOIN images i ON first.id = i.id 

यह दिखाए गए एक अनुमानित छवि के साथ प्रति देश एक पंक्ति वापस करेगा।

+0

पीडी: मुझे उप-चयन से नफरत है! क्या वे धीमे नहीं हैं? – Tim

+1

मुझे लगता है, * उप-चयन * द्वारा, आपका मतलब है कि मेरे पास कुल मिलाकर शामिल होना है। मेरे अनुभव में, उनका प्रदर्शन अन्य क्वेरी प्रदर्शन की तरह है, जो इंडेक्स और अन्य ऐसी चीजों की पसंद से निर्धारित है। मैंने जो दिखाया है वह एक प्रश्न को तेज कर सकता है। यह पंक्तियों की संख्या को कम करने के लिए कम कर देता है। और कुल क्वेरी आश्चर्यजनक रूप से कुशल ढीले इंडेक्स स्कैन का उपयोग अपनी चीज़ के लिए कर सकती है। इसके बारे में पढ़ें। –

7

ANY_VALUE के बजाय, आप MIN या MAX कुल कार्यों का उपयोग कर सकते हैं।

वैकल्पिक रूप से, आप ONLY_FULL_GROUP_BY एसक्यूएल मोड है, जो MySql 5.7 के लिए सेट किया जाता है, और अंतर आप MySql 5.6 के साथ अनुभव के लिए जिम्मेदार है की स्थापना नहीं सोच सकते हैं। फिर आप अपने प्रश्नों के अपडेट में देरी कर सकते हैं जब तक कि आप अपने सभी वातावरण माइस्क्ल 5.7 में माइग्रेट नहीं कर लेते।

इनमें से कौन सा बेहतर विकल्प है, बहस योग्य है, लेकिन लंबी अवधि में यह आपके प्रश्नों को अनुकूलित करना बेहतर होगा ताकि वे ONLY_FULL_GROUP_BY नियम का पालन कर सकें। MIN या MAX का उपयोग करके निश्चित रूप से ऐसा करने में उपयोग किया जा सकता है।

+0

आपके समय और उत्तर के लिए धन्यवाद, wat द्वारा, ANY_VALUE संदर्भ http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value – Tim

+0

मेरे मामले में ANY_VALUE के बजाय MAX का उपयोग कर मेरी क्वेरी को MySQL 5.5 दोनों के लिए काम करने की अनुमति दी। और 5.7। सलाह के लिये धन्यवाद। –

3

दशकों आप प्रश्नों लिख सकता है कि मानक SQL में मान्य है, लेकिन पूरी तरह से वैध mysql नहीं थे के लिए

मानक SQL में, एक प्रश्न है कि शामिल BY खंड एक समूह का चयन करें सूची में nonaggregated स्तंभों को उल्लेख नहीं कर सकते हैं कि ग्रुप बाय क्लॉज में नामित नहीं हैं। उदाहरण के लिए, इस प्रश्न के मानक SQL में गैर कानूनी है ग्रुप द्वारा में प्रकट नहीं क्योंकि चयन सूची में nonaggregated नाम स्तंभ करता है:

चयन o.custid, c.name, मैक्स (o.payment) से आदेश एएस ओ, ग्राहक एएस सी WHERE o.custid = c.custid समूह द्वारा o.custid; पर क्वेरी के लिए कानूनी होने के लिए, ग्रुप बाय क्लॉज में नामित चयन सूची या से नाम कॉलम छोड़ा जाना चाहिए।

MySQL ग्रुप BY के मानक SQL उपयोग को बढ़ाता है ताकि चयन सूची ग्रुप बाय क्लॉज में नामित गैर-समेकित कॉलम का संदर्भ दे सके।

यह GROUP BY पर MySQL 5.6 मैनुअल पृष्ठ से आता है। यदि आप 5.7.6 के लिए एक ही पृष्ठ को देखते हैं तो आप देखते हैं कि चीजें बदली हैं। और नाटकीय रूप से बदल गया !!

वह पृष्ठ आपको समाधान भी देता है। ONLY_FULL_GROUP_BY अक्षम करें इससे आपकी पुरानी 5.6 क्वेरी 5.7.6 पर काम करने के लिए संभव हो जाएगी (आपकी क्वेरी से ANY_VALUE को हटाएं क्योंकि यह 5.7.6 में उपलब्ध नहीं है बल्कि इसके बजाय ONLY_FULL_GROUP_BY का उपयोग करें)।

+1

आपके समय और उत्तर के लिए धन्यवाद। – Tim

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