2013-03-17 12 views
5

मैं एक MySQL तालिका में संग्रहीत रिकॉर्ड साफ़ करने की कोशिश कर रहा हूं। यदि किसी पंक्ति में %X% है, तो सामग्री के बावजूद, मुझे उस पंक्ति और पंक्ति को तुरंत नीचे हटाने की आवश्यकता है। जैसे (खेद तालिका किसी की बुद्धि का अपमान किया गया है):MySQL में संबंधपरक स्थिति में एक रिकॉर्ड हटा दें?

| 1 | leave alone 
| 2 | Contains %X% - Delete 
| 3 | This row should also be deleted 
| 4 | leave alone 
| 5 | Contains %X% - Delete 
| 6 | This row should also be deleted 
| 7 | leave alone 

वहाँ यह करने के लिए एक तरह से प्रश्नों का केवल एक जोड़े का उपयोग कर है? या मुझे पहले एक SELECT क्वेरी निष्पादित करने की आवश्यकता है (%x% खोज पैरामीटर का उपयोग करके) तो उन परिणामों के माध्यम से लूप करें और एक DELETE निष्पादित करें ... प्रत्येक अनुक्रमणिका के लिए कहां लौटा + 1

+0

@Aiias: यह एक बिल्कुल अलग सवाल है। – duskwuff

उत्तर

0

ऐसा करने का कोई उचित तरीका नहीं है एक ही प्रश्न में (यह संभव हो सकता है लेकिन क्वेरी आप अंत का उपयोग किए अनुचित रूप से जटिल हो जाएगा, और लगभग निश्चित रूप से अन्य एसक्यूएल इंजन के लिए पोर्टेबल नहीं होगा।)

उपयोग का चयन करें-तो-Delete दृष्टिकोण आप में वर्णित आपका प्रश्न।

2

यह काम करना चाहिए, हालांकि इसकी एक सा भद्दा (जैसे तर्क जांच करना चाह सकते के रूप में यह (टिप्पणी देखें) table से हटा दें। db कहां में idcol (db से idcol का चयन करें। table कहां col तरह मिलान पैटर्न का उपयोग करता '% एक्स%') या idcol IN (SELECT idcol +1 FROM db . तालिका WHERE col` की तरह '% एक्स%')

+0

यह आईडी में अंतर नहीं पर निर्भर करता है। – CBroe

+0

हाँ यह बहुत सच है – Tucker

+0

LIKE regexes का उपयोग नहीं करता है, REGEXP करता है; http://dev.mysql.com/doc/refman/5.6/en/string-comparison-functions.html#operator_like देखें – ysth

1

मान तालिका test नामित और 0 नाम कॉलम के लिए निहित था चलोऔर data

हम एक का चयन करें हमें सभी पंक्तियों एक पिछली पंक्ति (सभी आईडी के उच्चतम आईडी कम हमारे वर्तमान पंक्ति के आईडी से) है कि आईडी देता है कि के साथ शुरू:

SELECT t1.id FROM test t1 
    JOIN test t2 ON 
    (t2.id, true) 
     = 
    (SELECT t3.id, t3.data LIKE '%X%' FROM test t3 
     WHERE t3.id < t1.id ORDER BY id DESC LIMIT 1) 

हमें आईडी देता है कि 3 और 6. उनकी पिछली पंक्तियों में 2 और 5 में %X% है, इसलिए यह अच्छा है।

अब, पंक्तियों %X% होती है और उन्हें पिछले अभियानों के साथ गठबंधन की आईडी प्राप्त करने देता यूनियन के माध्यम से:

(SELECT t1.id FROM test t1 
    JOIN test t2 ON 
    (t2.id, true) 
     = 
    (SELECT t3.id, t3.data LIKE '%X%' FROM test t3 
     WHERE t3.id < t1.id ORDER BY id DESC LIMIT 1) 
) 
UNION 
(
    SELECT id FROM test WHERE data LIKE '%X%' 
) 

हमें 3, 6, 2, 5 देता है कि - अच्छा!

अब, हम किसी तालिका से हटा नहीं सकते हैं और MySQL में उसी तालिका से चयन नहीं कर सकते हैं - इसलिए अस्थायी तालिका का उपयोग करें, हमारे आईडी को संग्रहीत करें जिन्हें हटाया जाना है, और फिर उस अस्थायी तालिका को हटाने के लिए पढ़ें हमारे मूल मेज से:

CREATE TEMPORARY TABLE deleteids (id INT); 

INSERT INTO deleteids 
    (SELECT t1.id FROM test t1 
    JOIN test t2 ON 
     (t2.id, true) 
     = 
     (SELECT t3.id, t3.data LIKE '%X%' FROM test t3 
      WHERE t3.id < t1.id ORDER BY id DESC LIMIT 1) 
) 
    UNION 
    (
    SELECT id FROM test WHERE data LIKE '%X%' 
); 

    DELETE FROM test WHERE id in (SELECT * FROM deleteids); 

... और हम छोड़ दिया जाता है आईडी 1, 4 और 7 हमारे test तालिका में साथ!

(और चूंकि पिछली पंक्तियों का चयन <, ऑर्डर बीई और एलटीटी का उपयोग करके किया जाता है, यह भी काम करता है अगर आईडी लगातार नहीं हैं।)

1

आप एक ही DELETE बयान में यह सब कर सकते हैं:

"पंक्ति के तुरंत बाद" यह मानते हुए अपने INT आधारित आईडी कॉलम के आदेश, आप पंक्ति संख्या आवंटित करने के लिए MySQL चर का उपयोग कर सकते हैं पर आधारित है अंतराल के लिए खातों अपनी आईडी में:

DELETE a FROM tbl a 
JOIN (
    SELECT a.id, b.id AS nextid 
    FROM (
     SELECT  a.id, a.text, @rn:[email protected]+1 AS rownum 
     FROM  tbl a 
     CROSS JOIN (SELECT @rn:=1) rn_init 
     ORDER BY a.id 
    ) a 
    LEFT JOIN (
     SELECT  a.id, @rn2:[email protected]+1 AS rownum 
     FROM  tbl a 
     CROSS JOIN (SELECT @rn2:=0) rn_init 
     ORDER BY a.id 
    ) b ON a.rownum = b.rownum 
    WHERE a.text LIKE '%X%' 
) b ON a.id IN (b.id, b.nextid) 

SQL Fiddle Demo (added additional data for example)


यह क्या करता है यह पहली बार अपने डेटा लेता है और उस पर आधारित रैंकों आपका आईडी कॉलम, फिर हम लगभग समान परिणाम परिणाम पर LEFT JOIN ऑफसेट करते हैं, सिवाय इसके कि रैंक कॉलम 1 के पीछे है।

SELECT a.id, a.text, b.id AS nextid, b.text AS nexttext 
FROM (
    SELECT  a.id, a.text, @rn:[email protected]+1 AS rownum 
    FROM  tbl a 
    CROSS JOIN (SELECT @rn:=1) rn_init 
    ORDER BY a.id 
) a 
LEFT JOIN (
    SELECT  a.id, a.text, @rn2:[email protected]+1 AS rownum 
    FROM  tbl a 
    CROSS JOIN (SELECT @rn2:=0) rn_init 
    ORDER BY a.id 
) b ON a.rownum = b.rownum 
WHERE a.text LIKE '%X%' 

पैदावार:: इस पंक्तियों और कंधे से उनके तत्काल "अगला" पंक्तियों पक्ष ताकि हम माता-पिता DELETE बयान में एक ही समय में उनके आईडी के दोनों खींच सकते हो जाता है

ID  | TEXT     | NEXTID | NEXTTEXT 
2  | Contains %X% - Delete | 3  | This row should also be deleted 
5  | Contains %X% - Delete | 6  | This row should also be deleted 
257 | Contains %X% - Delete | 3434  | This row should also be deleted 
4000 | Contains %X% - Delete | 4005  | Contains %X% - Delete 
4005 | Contains %X% - Delete | 6000  | Contains %X% - Delete 
6000 | Contains %X% - Delete | 6534  | This row should also be deleted 

हम फिर JOIN - DELETE कि इस शर्त पर पूरा विवरण कि वह पंक्तियों को हटा देता है जिनकी आईडी या तो "उप-चयन" ID या NEXTID हैं।

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