MySQL में select से डिलीट कैसे करें?


86

यह कोड MySQL 5.0 के लिए काम नहीं करता है, इसे काम करने के लिए कैसे फिर से लिखना है

DELETE FROM posts where id=(SELECT id FROM posts GROUP BY id  HAVING ( COUNT(id) > 1 ))

मैं उन स्तंभों को हटाना चाहता हूं जिनमें अद्वितीय आईडी नहीं है। मैं जोड़ूंगा कि ज्यादातर समय इसकी केवल एक आईडी (मैंने वाक्य रचना में कोशिश की और यह अच्छी तरह से काम नहीं करता है)।

जवाबों:


212

SELECT(उप) क्वेरी परिणाम सेट लौटाता है । इसलिए आपको अपने खंड में INनहीं, उपयोग करने की आवश्यकता है ।=WHERE

इसके अतिरिक्त, जैसा कि इस उत्तर में दिखाया गया है कि आप एक ही क्वेरी के भीतर एक उप-तालिका से एक ही तालिका को संशोधित नहीं कर सकते हैं। हालाँकि, आप या SELECTतो DELETEअलग-अलग प्रश्नों में हो सकते हैं , या किसी अन्य उपश्रेणी को घोंसला बना सकते हैं और आंतरिक उप-परिणाम परिणाम को अलियास कर सकते हैं (हालांकि, यह बहुत आसान है, यद्यपि)

DELETE FROM posts WHERE id IN (
    SELECT * FROM (
        SELECT id FROM posts GROUP BY id HAVING ( COUNT(id) > 1 )
    ) AS p
)

या Mchl द्वारा सुझाए गए जॉइन का उपयोग करें ।


1
मेरे पास 150 डुप्लिकेट कुंजियों वाली एक मेज थी। मैंने उपरोक्त क्वेरी को निष्पादित किया और इसने कहा "144 पंक्तियाँ प्रभावित", लेकिन वहां जहां अभी भी डुप्लिकेट कुंजियाँ हैं। इसलिए मैंने फिर से क्वेरी निष्पादित की और यह कहता है कि 5 पंक्तियाँ प्रभावित हुईं, फिर से: 1 पंक्ति प्रभावित। फिर सभी डुप्लीकेट चाबियां जहां चली गईं। ऐसा क्यों है?
एलेक्स

ऐसा इसलिए हो रहा है, क्योंकि आपके डुप्लिकेट के प्रत्येक सेट में से केवल 1 प्रविष्टि को हटा रहा है:SELECT id FROM posts GROUP BY id HAVING ( COUNT(id) > 1 )
havvg

# 1248 - प्रत्येक व्युत्पन्न तालिका का अपना अलग नाम होना चाहिए
थान

@ थंग: यही कारण है कि मैंने कहा कि आंतरिक उपश्रेणी उर्फ।
BoltClock

1
क्या आप कृपया बताएंगे कि "As p" क्या करता है?
क्रिकेटर

22
DELETE 
  p1
  FROM posts AS p1 
CROSS JOIN (
  SELECT ID FROM posts GROUP BY id HAVING COUNT(id) > 1
) AS p2
USING (id)

यह काम करने के लिए प्रकट होता है, लेकिन मैं वाक्य रचना द्वारा भ्रमित हूं और इसे समझाने के लिए कहीं और कोई संसाधन नहीं पा सकता हूं। CROSS JOINजाहिरा तौर पर एक कार्टेज़ियन जॉइन करता है, इसलिए ऐसा लगता है कि यह अनावश्यक काम कर सकता है, या उप-प्रदर्शन कर सकता है? क्या कोई समझा सकता है?
विंटरन

यह एक कार्टेजियन प्रोडक्ट तभी करेगा जब कोई USINGक्लॉज न हो। साथ USINGउत्पाद में समान मान होने जोड़े के लिए सीमित है idस्तंभ, तो यह वास्तव में बहुत ही सीमित है।
21

क्या आप आंतरिक जुड़ाव के साथ भी ऐसा ही कर सकते थे? आईईDELETE p1 FROM posts AS p1 INNER JOIN ( SELECT ID FROM posts GROUP BY id HAVING COUNT(id) > 1 ) AS p2 ON p2.ID=p1.ID
कोडोस जॉनसन

1
@Andrew: हाँ। कार्यात्मक रूप से ये जोड़ बिल्कुल एक जैसे होते हैं।
Mchl

5

आप आंतरिक जुड़ाव का उपयोग कर सकते हैं:

DELETE 
    ps 
FROM 
    posts ps INNER JOIN 
         (SELECT 
           distinct id 
         FROM 
             posts 
         GROUP BY id  
      HAVING COUNT(id) > 1 ) dubids on dubids.id = ps.id  

0

यदि आप सभी डुप्लिकेट हटाना चाहते हैं, लेकिन डुप्लिकेट के प्रत्येक सेट में से एक, यह एक समाधान है:

DELETE posts
FROM posts
LEFT JOIN (
    SELECT id
    FROM posts
    GROUP BY id
    HAVING COUNT(id) = 1

    UNION

    SELECT id
    FROM posts
    GROUP BY id
    HAVING COUNT(id) != 1
) AS duplicate USING (id)
WHERE duplicate.id IS NULL;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.