SQL सब उप क्वेरी का उपयोग करके कैसे हटा सकता है


15

तालिका से डुप्लिकेट रिकॉर्ड को हटाने के लिए हमारे डेवलपर्स द्वारा निम्न कोड जोड़ा गया था:

DELETE  SubQuery

FROM
(
    SELECT  ID
            ,FK1
            ,FK2
            ,CreatedDateTime
            ,ROW_NUMBER() OVER(PARTITION BY FK1, FK2 ORDER BY CreatedDateTime) AS RowNumber

    FROM    Table
)
AS SubQuery

WHERE   RowNumber > 1

कोड की समीक्षा करते समय, मैंने यह मान लिया कि यह काम नहीं करेगा, लेकिन हमारे परीक्षण वातावरण (SQL 2014) में इसका परीक्षण करने से पता चलता है कि यह करता है!

SQL उप क्वेरी को हल करने और अभिलेखों को हटाने से कैसे जानता है table?

जवाबों:


14

subqueryअपने कोड में आप एक कहा जाता है व्युत्पन्न तालिका । यह आधार तालिका नहीं है बल्कि एक तालिका है जो उस समय के दौरान "रहती है" जब क्वेरी चलती है। विचारों की तरह (जिसे देखा टेबल भी कहा जाता है ) - और हाल के संस्करणों में सीटीई जो एक और है, एक क्वेरी के अंदर एक तालिका को "परिभाषित" करने का 4 वां तरीका है - वे कई मायनों में एक तालिका के समान हैं। आप selectउनसे कर सकते हैं, आप उन्हें अन्य तालिकाओं (आधार या नहीं!) में fromया उनमें उपयोग कर सकते हैं join

कुछ DBMS में, (सभी DBMS ने इसे एक ही तरीके से लागू नहीं किया है) ये टेबल / विचार अद्यतन करने योग्य हैं । और "अद्यतन करने योग्य" का मतलब है कि हम भी update, उनमें से insertया deleteउनसे कर सकते हैं।

हालांकि प्रतिबंध हैं और यह अपेक्षित है। कल्पना कीजिए कि अगर subquery2 (या 17 टेबल) में शामिल हुआ था। deleteतब क्या मतलब होगा ? (किन तालिकाओं से पंक्तियों को हटा दिया जाना चाहिए?) अद्यतन करने योग्य विचार बहुत जटिल मामला है । हाल ही में (2012) पुस्तक है, पूरी तरह से इस विषय पर, क्रिस डेट द्वारा लिखित, रिलेशनल सिद्धांत में प्रसिद्ध विशेषज्ञ: व्यू अपडेटिंग और रिलेशनल थ्योरी

जब व्युत्पन्न तालिका (या दृश्य) एक बहुत ही सरल क्वेरी होती है, जैसे कि इसमें केवल एक आधार तालिका होती है (संभवतः द्वारा प्रतिबंधित है WHERE) और नहीं GROUP BY, तो व्युत्पन्न तालिका की प्रत्येक पंक्ति अंतर्निहित आधार तालिका में एक पंक्ति से मेल खाती है, इसलिए यह है इसे अपडेट, सम्मिलित या हटाने के लिए आसान *

जब उपकुंजी के अंदर कोड अधिक जटिल होता है, तो यह इस बात पर निर्भर करता है कि व्युत्पन्न तालिका / दृश्य की पंक्तियों को अंतर्निहित आधार तालिकाओं में से पंक्तियों से पता लगाया / हल किया जा सकता है या नहीं।

SQL सर्वर के लिए, आप MSDN में अद्यतन दृश्य परिच्छेद में अधिक पढ़ सकते हैं CREATE VIEW:।

अद्यतन दृश्य

आप एक अंतर्निहित बेस टेबल के डेटा को एक दृश्य के माध्यम से संशोधित कर सकते हैं, जब तक कि निम्नलिखित स्थितियां सत्य नहीं होती हैं:

  • किसी भी संशोधन, सहित UPDATE, INSERTऔर DELETEकथन, केवल एक आधार तालिका से कॉलम को संदर्भित करना चाहिए।

  • दृश्य में संशोधित किए जा रहे स्तंभों को तालिका स्तंभों में अंतर्निहित डेटा को सीधे संदर्भित करना चाहिए। स्तंभों को किसी अन्य तरीके से प्राप्त नहीं किया जा सकता है, जैसे कि निम्नलिखित के माध्यम से:

  • एक समग्र समारोह: AVG, COUNT, SUM, MIN, MAX, GROUPING, STDEV, STDEVP, VAR, और VARP

  • एक संगणना। स्तंभ को अन्य स्तंभों का उपयोग करने वाले अभिव्यक्ति से गणना नहीं की जा सकती है। कॉलम है कि सेट ऑपरेटरों का उपयोग करके बनते हैं UNION, UNION ALL, CROSSJOIN, EXCEPT, और INTERSECT एक गणना करने के लिए राशि और भी updatable नहीं हैं।

  • कॉलम संशोधित किया जा रहा से प्रभावित नहीं हैं GROUP BY, HAVINGया DISTINCTखंड।

  • TOPक्लॉज़ के साथ दृश्य के select_statement में कहीं भी उपयोग नहीं किया जाता है WITH CHECK OPTION

पिछले प्रतिबंध किसी भी उपश्रेणी FROMके दृश्य के खंड में लागू होते हैं, ठीक वैसे ही जैसे वे दृश्य पर लागू होते हैं। आम तौर पर, डेटाबेस इंजन दृश्य परिभाषा से एक बेस टेबल पर स्पष्ट रूप से संशोधनों का पता लगाने में सक्षम होना चाहिए।


वास्तव deleteमें आसान है, की तुलना में कम जटिल है update। SQL सर्वर को केवल प्राथमिक कुंजी या किसी अन्य तरीके से यह पहचानने की आवश्यकता है कि बेस टेबल की कौन सी पंक्तियों को हटाना है। इसके लिए update, एक अतिरिक्त (बल्कि स्पष्ट) प्रतिबंध है कि हम एक गणना किए गए कॉलम को अपडेट नहीं कर सकते। आप अपडेट करने के लिए अपनी क्वेरी को संशोधित करने का प्रयास कर सकते हैं। CreatedDateTimeवसीयत को अपडेट करना शायद ठीक काम करेगा लेकिन गणना किए गए RowNumberकॉलम को अपडेट करने की कोशिश करने से त्रुटि पैदा होगी। और insertभी अधिक जटिल है, क्योंकि हमें आधार तालिका के सभी स्तंभों के लिए मान प्रदान करना होगा जिनमें कोई DEFAULTबाधा नहीं है ।


4

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

विशेष रूप से डुप्लिकेट को हटाने के लिए उपश्रेणियों और सीटीई से हटाना पूरी तरह से समर्थित और बहुत कुशल है। मुझे SQL सर्वर के पुराने संस्करणों पर इसका उपयोग करना याद है।

मेरे एक पुराने ब्लॉग पोस्ट में अधिक ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.