SQL में डेटाबेस तालिका से सभी लेकिन शीर्ष n हटाएं


85

Sql में सभी पंक्तियों को हटाने का सबसे अच्छा तरीका क्या है, लेकिन शीर्ष पर पंक्तियों की संख्या को रखना है?

जवाबों:


80
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)

संपादित करें:

क्रिस एक अच्छा प्रदर्शन लाता है क्योंकि प्रत्येक पंक्ति के लिए TOP 10 क्वेरी चलाई जाएगी। यदि यह एक बार की बात है, तो यह एक सौदे के रूप में बड़ा नहीं हो सकता है, लेकिन अगर यह एक सामान्य बात है, तो मैं इसे करीब से देखता था।


4
अगर किसी को आमतौर पर सभी शीर्ष पंक्तियों को हटाने की आवश्यकता होती है, तो मैं तर्क दूंगा कि उन्हें चिंता करने के लिए बड़े मुद्दे मिल गए हैं।
डैनियल शेफ़र

6
बस एक नोट है कि आप या तो एक अस्थायी तालिका बनाने के माध्यम से सबक्वेरी परफॉर्मेंस इश्यू को मैन्युअल रूप से हल कर सकते हैं (यह मानते हुए कि यह एक अपरिमेय ऑपरेशन है) या क्वेरी लिखने के रूप DELETE FROM Table WHERE ID NOT IN (SELECT id FROM (SELECT TOP 10 ID FROM Table) AS x)में MySQL को एक अस्थायी तालिका बनाने के लिए मजबूर करें।
माइकल मिऑर

धन्यवाद। यह एक जीवन रक्षक था :)
Si8

1
उपकुंजी कई बार चलती है, क्या यह सच है? stackoverflow.com/questions/18790796/…
djluis

5
@ डैनियल शेफ़र ऐसा नहीं लगता जैसे उन्हें कोई डीबी या व्यावसायिक तर्क मुद्दा मिला हो। पूरी तरह से सामान्य अवधारण नीति की तरह लगता है।
हेजजमैन

33

मैं आईडी कॉलम (पंक्तियों) का चयन करूँगा, जिन्हें आप एक टेम्‍प टेबल या टेबल वैरिएबल में रखना चाहते हैं। फिर उन सभी पंक्तियों को हटा दें जो अस्थायी तालिका में मौजूद नहीं हैं। किसी अन्य उपयोगकर्ता द्वारा उल्लिखित वाक्यविन्यास:

DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)

एक संभावित समस्या है। तालिका में प्रत्येक पंक्ति के लिए "सेलेक्ट टॉप 10" क्वेरी को निष्पादित किया जाएगा, जो एक बहुत बड़ा प्रदर्शन हिट हो सकता है। आप एक ही क्वेरी को बार-बार बनाने से बचना चाहते हैं।

यह सिंटैक्स काम करना चाहिए, जो आपने अपने मूल एसक्यूएल बयान के रूप में सूचीबद्ध किया है:

create table #nuke(NukeID int)

insert into #nuke(Nuke) select top 1000 id from article

delete article where not exists (select 1 from nuke where Nukeid = id)

drop table #nuke

3
insert into #nuke(Nuke) ...शायद होना चाहिए: insert into #nuke(NukeID) ...साथ ही नाम nuke भ्रामक है क्योंकि आप इन पंक्तियों को हटाने की कोशिश नहीं कर रहे हैं। nuke शायद इस तथ्य के नाम पर है कि इसे हटा दिया जाएगा।
एर्नो

12

उन लोगों के लिए भविष्य का संदर्भ जो MS SQL का उपयोग नहीं करते हैं।

PostgreSQL उपयोग में ORDER BYऔर LIMITइसके बजाय TOP

DELETE FROM table
WHERE id NOT IN (SELECT id FROM table ORDER BY id LIMIT n);

MySQL - अच्छी तरह से ...

त्रुटि - MySQL का यह संस्करण अभी तक 'LIMIT & IN / ALL / any / SOME सबक्वेरी' का समर्थन नहीं करता है

अभी तक मेरा अनुमान नहीं है।


5

मुझे लगता है कि एक वर्चुअल टेबल का उपयोग करना एक इन-क्लॉज या टेम्प टेबल से बेहतर होगा।

DELETE 
    Product
FROM
    Product
    LEFT OUTER JOIN
    (
        SELECT TOP 10
            Product.id
        FROM
            Product
    ) TopProducts ON Product.id = TopProducts.id
WHERE
    TopProducts.id IS NULL

2

मैं अन्य स्वादों के बारे में नहीं जानता, लेकिन MySQL DELETE LIMIT की अनुमति देता है।

यदि आप चीजों को ऑर्डर कर सकते हैं ताकि आप जिस एन पंक्तियों को रखना चाहते हैं, वह सबसे नीचे हो, तो आप टेबल लिमिट टेबल-एन से डिलीट कर सकते हैं।

संपादित करें

Oooo। मुझे लगता है कि मुझे Cory फॉय का जवाब बेहतर लगता है, यह मानते हुए कि यह आपके मामले में काम करता है। तुलना करने से मेरा तरीका थोड़ा क्लिंकी लगता है।


2

यह वास्तव में भाषा विशिष्ट होने जा रहा है, लेकिन मैं संभवतः SQL सर्वर के लिए निम्नलिखित की तरह कुछ का उपयोग करेगा।

declare @n int
SET @n = SELECT Count(*) FROM dTABLE;
DELETE TOP (@n - 10 ) FROM dTable

यदि आप पंक्तियों की सही संख्या की परवाह नहीं करते हैं, तो हमेशा होता है

DELETE TOP 90 PERCENT FROM dTABLE;

1
न ही ये काम। सवाल पूछता है कि तालिका में केवल शीर्ष एन पंक्तियों को कैसे रखा जाए। इन दोनों उदाहरणों में केवल नीचे की N पंक्तियाँ हैं।
क्रिस

1
MSSQL में ठीक काम करता है। बस शीर्ष के बजाय नीचे हटाने के लिए एक छँटाई जोड़ें?
मीनग्रीन

2

यहाँ देखें कि मैंने यह कैसे किया। यह विधि अधिक तेज़ और सरल है:

OFFSET कमांड का उपयोग करके MS SQL में डेटाबेस टेबल से सभी लेकिन शीर्ष n को हटा दें

WITH CTE AS
    (
    SELECT  ID
    FROM    dbo.TableName
    ORDER BY ID DESC
    OFFSET 11 ROWS
    )
DELETE CTE;

उस IDकॉलम से प्रतिस्थापित करें जिसके द्वारा आप सॉर्ट करना चाहते हैं। OFFSETउन पंक्तियों की संख्या के बाद नंबर बदलें, जिन्हें आप हटाना चाहते हैं। चुनें DESCया ASC- जो भी आपके मामले के अनुरूप हो।


इस मामले में आप उन पंक्तियों की संख्या को ऑफ़सेट नहीं करेंगे जिन्हें आप रखना चाहते हैं?
नैपकिनबेक

@ नेपकीनबॉच हाँ।
हार्वे

0

मैं इसे नीचे दी गई तकनीक का उपयोग करके हल करूंगा। उदाहरण प्रत्येक पंक्ति पर एक आईडी के साथ एक लेख तालिका की अपेक्षा करता है ।

Delete article where id not in (select top 1000 id from article)

संपादित करें: मेरे स्वयं के प्रश्न का उत्तर देने के लिए बहुत धीमा ...


0

पुनर्संशोधित?

Delete a From Table a Inner Join (
    Select Top (Select Count(tableID) From Table) - 10) 
        From Table Order By tableID Desc
) b On b.tableID = A.tableID

संपादित करें: उन दोनों को क्वेरी विश्लेषक में आज़माया गया, वर्तमान उत्तर को उपवास किया गया (लानत आदेश द्वारा ...)


0

बेहतर तरीका यह होगा कि आप उन पंक्तियों को सम्मिलित करें जिन्हें आप किसी अन्य तालिका में चाहते हैं, मूल तालिका को छोड़ दें और फिर नई तालिका का नाम बदलें, इसलिए इसका नाम पुरानी तालिका के समान है


क्यों बेहतर है? और तेज? पूरा करने के लिए कुछ अतिरिक्त आदेशों की आवश्यकता है।
मीनग्रीन

0

मुझे TOPहर पंक्ति के लिए अभिव्यक्ति निष्पादित करने से बचने के लिए एक ट्रिक मिली है । हम जिस चीज को रखना चाहते हैं उसे पाने के लिए हम TOPसाथ जोड़ सकते हैं । फिर हम सब कुछ से अधिक हटा देते हैं ।MAXMaxIdMaxId

-- Declare Variable to hold the highest id we want to keep. 
DECLARE @MaxId as int = (
SELECT MAX(temp.ID)
FROM (SELECT TOP 10 ID FROM table ORDER BY ID ASC) temp
)

-- Delete anything greater than MaxId. If MaxId is null, there is nothing to delete.
IF @MaxId IS NOT NULL
    DELETE FROM table WHERE ID > @MaxId

नोट: उचित परिणाम सुनिश्चित ORDER BYकरने के MaxIdलिए घोषणा करते समय उपयोग करना महत्वपूर्ण है ।

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