এসকিউএল ডাটাবেস টেবিল থেকে শীর্ষ এন বাদে সমস্ত মুছুন


86

বর্ধিত সারণীতে সমস্ত সারি মুছে ফেলার সর্বোত্তম উপায় কী তবে শীর্ষে n সংখ্যক সারি রাখা?

উত্তর:


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

সম্পাদনা করুন:

ক্রিস একটি ভাল পারফরম্যান্স হিট এনেছে যেহেতু প্রতিটি সারিতে শীর্ষ 10 কোয়েরি চালানো হবে। এটি যদি এক সময়ের জিনিস হয়, তবে এটি কোনও চুক্তির মতো বড় নাও হতে পারে, তবে এটি যদি সাধারণ জিনিস হয় তবে আমি এটির কাছাকাছি নজর রেখেছি।


6
কেবলমাত্র একটি নোট যে আপনি ম্যানুয়ালি একটি অস্থায়ী টেবিল তৈরির মাধ্যমে subquery পারফরম্যান্স সমস্যাটি সমাধান করতে পারেন (এটি একটি বিরল অপারেশন বলে ধরে নেওয়া) বা DELETE FROM Table WHERE ID NOT IN (SELECT id FROM (SELECT TOP 10 ID FROM Table) AS x)মাইএসকিউএলকে অস্থায়ী টেবিল তৈরি করতে বাধ্য করার জন্য কোয়েরিটি লিখেছেন ।
মাইকেল মায়ার

ধন্যবাদ. এটি জীবন
রক্ষাকারী

4
Subquery একাধিকবার চালানো, এটা কি সত্য? stackoverflow.com/questions/18790796/...
djluis

4
@ ড্যানিয়েল শেফার তাদের কোনও ডিবি বা ব্যবসায়িক যুক্তি সম্পর্কিত সমস্যা পেয়েছে বলে মনে হয় না। পুরোপুরি স্বাভাবিক ধরে রাখার নীতিমালা বলে মনে হচ্ছে।
হেজাজমান

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

4
insert into #nuke(Nuke) ...সম্ভবত হওয়া উচিত: insert into #nuke(NukeID) ...এছাড়াও নাম নিউক বিভ্রান্তিকর কারণ আপনি এই সারিগুলি মোছার চেষ্টা করছেন না। নুকে সম্ভবত মুছে ফেলা হবে এই সত্যটির নামকরণ করা হয়েছে।
এর্নো

12

যারা এমএস এসকিউএল ব্যবহার করেন না তাদের জন্য ভবিষ্যতের রেফারেন্স।

PostgreSQL এ ORDER BYএবং এর LIMITপরিবর্তে ব্যবহার করুন TOP

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

মাইএসকিউএল - ভাল ...

ত্রুটি - মাইএসকিউএলের এই সংস্করণটি এখনও 'লিমিটেড এবং ইন / সমস্ত / কোনও / কোনও উপ-উপকরণ' সমর্থন করে না

এখনও আমি অনুমান করি না।


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

আমি অন্যান্য স্বাদ সম্পর্কে জানি না তবে মাইএসকিউএল মোছার সীমাবদ্ধতা দেয়।

আপনি যদি জিনিসগুলি অর্ডার করতে পারেন যাতে আপনি যে এন সারিগুলি রাখতে চান তার নীচে থাকে, তবে আপনি সারণী থেকে সরিয়ে ফেলতে পারেন সীমাবদ্ধ টেবিল কাউন্ট-এন।

সম্পাদনা করুন

ওওও। আমি মনে করি যে এটি আপনার ক্ষেত্রে কার্যকর হয় তা ধরে নিয়ে আমি কোরি ফয়ের উত্তরটি আরও ভাল পছন্দ করি । আমার উপায় তুলনা করে কিছুটা ক্লিঙ্কি বোধ করে।


2

এটি সত্যিই ভাষা নির্দিষ্ট হতে চলেছে, তবে আমি সম্ভবত এসকিউএল সার্ভারের জন্য নিম্নলিখিতগুলির মতো কিছু ব্যবহার করব।

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

আপনি যদি সারিগুলির সঠিক সংখ্যা সম্পর্কে চিন্তা না করেন তবে সর্বদা থাকে

DELETE TOP 90 PERCENT FROM dTABLE;

4
এই কাজগুলির কোনোটাই নয়। প্রশ্নটি জিজ্ঞাসা করে যে কীভাবে কেবল টেবিলের উপরে শীর্ষ এন সারি রাখতে হবে। এই দুটি উদাহরণই নীচের এন সারি রাখে।
ক্রিস

4
এমএসএসকিউএলে সূক্ষ্মভাবে কাজ করে। শীর্ষের পরিবর্তে নীচের অংশটি মুছতে কেবল বাছাই করুন?
মিনগ্রিন

2

এখানে আমি এটি কীভাবে করেছি। এই পদ্ধতিটি দ্রুত এবং সহজ:

অফসেট কমান্ডটি ব্যবহার করে এমএস এসকিউএলে ডাটাবেস টেবিল থেকে শীর্ষ 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

আরও ভাল উপায় হ'ল যে সারিগুলি আপনি চাইছেন তা অন্য টেবিলের মধ্যে sertোকানো, আসল টেবিলটি ফেলে দিন এবং নতুন টেবিলটির নতুন নামকরণ করুন যাতে এটি পুরাতন সারণির মতোই নাম রাখে


কেন যে ভাল? আরও দ্রুত? সম্পাদনের জন্য বেশ কয়েকটি অতিরিক্ত কমান্ডের প্রয়োজন।
মিনগ্রিন

0

আমি TOPপ্রতি সারির জন্য প্রকাশটি এড়াতে একটি কৌশল পেয়েছি । আমরা একত্রিত করতে পারেন TOPসঙ্গে MAXপেতে MaxIdআমরা রাখতে চাই। তারপরে আমরা এর চেয়ে বড় কিছু মুছুন MaxId

-- 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করার সময় ব্যবহার করা গুরুত্বপূর্ণ important

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.