sql select - चुनें * टैबलेटनाम से कहां 1




sport in (9)

मैं उत्सुक हूँ। इन संबंधित प्रश्नों के बीच अंतर क्या हैं:

  1. SELECT * FROM `tablename`

  2. SELECT * FROM `tablename` WHERE 1

  3. SELECT * FROM `tablename` WHERE 1=1


Answers

1 में, MySQL को किसी भी WHERE शर्तों का मूल्यांकन करने की आवश्यकता नहीं है।

2 और 3 में, जहां स्थिति स्थिर है और पंक्तियों के मूल्यों पर आधारित नहीं है। यह बूलियन तर्क के साथ मूल्यांकन किया जाएगा और हमेशा सच हो जाएगा।

कार्यात्मक रूप से, कोई अंतर नहीं है। आपको कोड स्पष्टता के लिए 1 चुनना चाहिए।


1 - चयन करें * table_name से यह आपको किसी भी कथन को चलाने के साथ तालिका के सभी रिकॉर्ड देगा।

2 - चयन करें * table_name से जहां यह स्थिति हमेशा सत्य होती है, इसका उपयोग हैकर द्वारा किसी भी सिस्टम में जाने के लिए किया जाता है। यदि आपने 2 और 3 की तुलना में एसक्यूएल इंजेक्शन के बारे में सुना है तो वे परिदृश्य हैं जिन्हें तालिका के सभी रिकॉर्ड प्राप्त करने के लिए हैकर द्वारा निर्माण करने के लिए मजबूर किया जाता है।

3 - चयन करें * table_name से जहां 1 = 1 यह आपको तालिका के सभी रिकॉर्ड्स देगा लेकिन यह कहां से कथन की तुलना करेगा और फिर आगे बढ़ेगा, इसके मूल रूप से इसके बाद और कथन को जोड़ने या हटाने के लिए जोड़ा गया है।


वे सभी एक ही जवाब आउटपुट करते हैं। हालांकि जिस तरह से 2 और 3 लिखा गया है वह ज्यादातर "कहां" कथन पर नियंत्रण रखने के लिए है, इसलिए इससे इसे जोड़ना या बाद में इसे हटा देना आसान हो जाएगा।

मुझे लगता है कि पहला और तीसरा तरीका इसे लिखने का सही तरीका है। यदि आपको किसी ऐसे कथन की आवश्यकता है जो आप नंबर 3 की तरह करते हैं अन्यथा नंबर 1 पर्याप्त होगा।


सभी समान हैं लेकिन 2 और 3 का उपयोग AND / OR स्थितियों के लिए गतिशील क्वेरी बनाने के लिए किया जाता है

sqlquery ="  SELECT * FROM `tablename` where 1 =1 "

हम गतिशील क्वेरी बनाने के लिए 2 और 3 प्रारूप का उपयोग करते हैं, इसलिए हम पहले ही जानते हैं कि "कहां" कीवर्ड जोड़ा गया है और हम और अधिक फ़िल्टर जोड़ते रहते हैं। पसंद

sqlquery  = sqlquery + "and columna =a"
"AND columna =a " then

कुछ पंक्तियों के बाद यदि हमारे पास नए फ़िल्टर हैं तो हम "AND coulmnb = b" और इसी तरह जोड़ते हैं

आपको एसक्यूएल क्वेरी की जांच करने की आवश्यकता नहीं है, जहां कीवर्ड को पहली या प्रारंभिक क्वेरी में रखा गया है

SELECT * FROM `tablename` WHERE 1=1 AND (columnname1 = 'Value' OR columnname2 = 'Value')

अन्यथा हम sqlquery = "SELECT * FROM tablename" लिख सकते हैं sqlquery = "SELECT * FROM tablename"

फिर

यदि sqlquery में कोई 'कहां' खंड नहीं है

sqlquery  = sqlquery + "where columna =a"

अन्य

sqlquery  = sqlquery + "and columna =a"

जैसा कि आप जानते हैं, सभी तीन एक ही परिणाम उत्पन्न करते हैं। (एक बुलियन संदर्भ में, MySQL पूर्णांक "1" को सच मानता है - असल में, "0" नहीं होने वाली किसी भी संख्या को सत्य माना जाता है)।

WHERE खंड में निरंतर स्थितियों को हटाने के लिए MySQL ऑप्टिमाइज़र स्पष्ट रूप से documented किया गया है:

  • निरंतर स्थिति हटाने। । ।:

    (बी> = 5 और बी = 5) या (बी = 6 और 5 = 5) या (बी = 7 और 5 = 6) -> बी = 5 या बी = 6

इसलिए, सभी तीनों को एक ही कोड में संकलित किया जाएगा।

वे सभी कार्यात्मक रूप से समकक्ष हैं और समान प्रदर्शन विशेषताओं के साथ होना चाहिए।

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

गतिशील WHERE खंडों का निर्माण करते समय अक्सर तीसरा उपयोग किया जाता है। यह अतिरिक्त शर्तों को जोड़ने के लिए आसान बनाता है AND <condition> lingering AND s के बारे में चिंता किए बिना।


परिणाम - सभी तीन प्रश्नों के लिए tablename के बजाय निर्दिष्ट तालिका में सभी रिकॉर्ड्स देता है

SELECT * FROM tablename WHERE 1 - इस answer जांच करें

SELECT * FROM tablename WHERE 1=1 - इस answer जांच करें

WHERE क्लॉज ऑप्टिमाइज़ेशन के बारे में अधिक जानकारी के लिए इन्हें जांचें: documented , SQLite , SQL


यदि आप प्रदर्शन और परिणामों में मतभेदों के बारे में पूछ रहे हैं, तो कोई भी नहीं है, 2 और 3 वही हैं WHERE TRUE , और वे परिणाम पहले के समान होंगे।

1 - SELECT * FROM table_name

table_name से सभी डेटा में परिणाम (कोई फ़िल्टर नहीं)

2 - SELECT * FROM table_name WHERE 1

1 का मूल्यांकन TRUE रूप में किया जाएगा, इसलिए - कोई फ़िल्टर नहीं - प्रत्येक रिकॉर्ड वापस कर दिया जाएगा।

3 - SELECT * FROM table_name where 1=1

आखिरी के समान, 1 = 1 एक TRUE अभिव्यक्ति है, इसलिए - कोई फ़िल्टर नहीं - प्रत्येक रिकॉर्ड का चयन किया जाएगा।


एमएस एसक्यूएल 1 और 3 में समान हैं, हालांकि, विकल्प 2 काम नहीं करेगा, विकल्प 2 एमएस एसक्यूएल में एक अमान्य बयान है, जहां कुछ मानों की तुलना करने के लिए उपयोग किया जाता है। उदाहरण के लिए:

  1. 'MyTable से * चुनें जहां आईडी = 3 (मान्य)
  2. 'MyTable से चुनें * जहां 1 = 1' myTable से चुनें * के समान है, जहां 2 = 2 'myTable से चुनें * के समान है जहां 3 = 3 आपको लगता है कि यह मान्य (मान्य) है * myTable' से चुनें

PostgreSQL में यह आमतौर पर सरल और तेज (नीचे अधिक प्रदर्शन अनुकूलन) है:

SELECT DISTINCT ON (customer)
       id, customer, total
FROM   purchases
ORDER  BY customer, total DESC, id;

या आउटपुट कॉलम की सामान्य संख्या के साथ छोटा (यदि स्पष्ट नहीं है):

SELECT DISTINCT ON (2)
       id, customer, total
FROM   purchases
ORDER  BY 2, 3 DESC, 1;

यदि total शून्य हो सकता है (किसी भी तरह से चोट नहीं पहुंचाएगा, लेकिन आप मौजूदा इंडेक्स से मेल खाना चाहते हैं):

...
ORDER  BY customer, total DESC NULLS LAST, id;

प्रमुख अंक

  • DISTINCT ON मानक का एक PostgreSQL एक्सटेंशन है (जहां पूरी SELECT सूची पर केवल DISTINCT परिभाषित किया गया है)।

  • DISTINCT ON क्लॉज में अभिव्यक्तियों की किसी भी संख्या की सूची बनाएं, संयुक्त पंक्ति मान डुप्लीकेट को परिभाषित करता है। नियम पुस्तिका:

    जाहिर है, यदि वे कम से कम एक कॉलम मान में भिन्न होते हैं तो दो पंक्तियों को अलग माना जाता है। इस तुलना में शून्य मानों को बराबर माना जाता है।

    बोल्ड जोर मेरा है।

  • DISTINCT ON को ORDER BY किया जा सकता है। प्रमुख अभिव्यक्तियों को उसी क्रम में अभिव्यक्तियों DISTINCT ON अग्रणी DISTINCT ON से मेल खाना पड़ेगा। आप सहकर्मियों के प्रत्येक समूह से एक विशेष पंक्ति चुनने के लिए ORDER BY अतिरिक्त अभिव्यक्ति जोड़ सकते हैं। मैंने संबंधों को तोड़ने के लिए id को अंतिम आइटम के रूप में जोड़ा:

    "उच्चतम total साझा करने वाले प्रत्येक समूह से सबसे छोटी id साथ पंक्ति चुनें।"

    यदि total शून्य हो सकता है, तो संभवतः आप सबसे बड़ी गैर-शून्य मान वाली पंक्ति चाहते हैं। प्रदर्शन की तरह NULLS LAST जोड़ें। विवरण:

  • SELECT सूची किसी भी तरह से DISTINCT ON या ORDER BY में अभिव्यक्तियों से बाधित नहीं है। (उपरोक्त साधारण मामले में आवश्यक नहीं है):

    • आपको DISTINCT ON या ORDER BY में किसी भी अभिव्यक्ति को शामिल करने की आवश्यकता नहीं है

    • आप SELECT सूची में कोई अन्य अभिव्यक्ति शामिल कर सकते हैं। यह सबक्वायरीज़ और कुल / विंडो फ़ंक्शंस के साथ अधिक जटिल प्रश्नों को बदलने के लिए महत्वपूर्ण है।

  • मैंने संस्करण 8.3 - 10 के साथ परीक्षण किया है लेकिन यह संस्करण संस्करण 7.1 के बाद से कम से कम रहा है, इसलिए मूल रूप से हमेशा।

सूची

उपर्युक्त क्वेरी के लिए एकदम सही अनुक्रमणिका एक बहु-कॉलम इंडेक्स होगी जो मेलिंग अनुक्रम में सभी तीन कॉलम फैलाएगी और मिलान क्रमबद्ध क्रम के साथ होगी:

CREATE INDEX purchases_3c_idx ON purchases (customer, total DESC, id);

असली दुनिया के अनुप्रयोगों के लिए बहुत विशिष्ट हो सकता है। लेकिन अगर पढ़ना प्रदर्शन महत्वपूर्ण है तो इसका इस्तेमाल करें। यदि आपके पास क्वेरी में DESC NULLS LAST है, तो इंडेक्स में इसका इस्तेमाल करें ताकि पोस्टग्रेस सॉर्ट ऑर्डर मैचों को जानता हो।

प्रभावशीलता / प्रदर्शन अनुकूलन

प्रत्येक क्वेरी के लिए एक अनुरूप सूचकांक बनाने से पहले आपको लागत और लाभ का वजन करना होगा। उपरोक्त सूचकांक की संभावना काफी हद तक डेटा वितरण पर निर्भर करती है।

इंडेक्स का उपयोग किया जाता है क्योंकि यह प्री-सॉर्ट किए गए डेटा को वितरित करता है, और पोस्टग्रेस 9.2 में या बाद में क्वेरी इंडेक्स से भी लाभ उठा सकती है, अगर इंडेक्स अंतर्निहित तालिका से छोटा है तो स्कैन करें । सूचकांक को पूरी तरह से स्कैन किया जाना चाहिए, यद्यपि।

बेंचमार्क

पोस्टग्रेस 9.1 के लिए मेरे पास एक साधारण बेंचमार्क था, जो 2016 तक पुराना था। इसलिए मैंने पोस्टग्रेस 9.4 और 9.5 के लिए एक बेहतर, पुनरुत्पादित सेटअप के साथ एक नया भाग लिया और विस्तृत परिणामों को एक और उत्तर में जोड़ा।





sql select-query