SQL'deki bir tablodan tüm satırları silmenin ancak n sayıda satırı en üstte tutmanın en iyi yolu nedir?
Yanıtlar:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Düzenle:
Her satır için İLK 10 sorgusu çalıştırılacağından, Chris iyi bir performans isabeti getiriyor. Bu tek seferlik bir şeyse, o kadar büyük bir anlaşma olmayabilir, ancak ortak bir şeyse, ona daha yakından baktım.
Geçici bir tablo veya tablo değişkeninde tutmak istediğiniz satır kümesini ID sütun (lar) ını seçerdim. Daha sonra geçici tabloda bulunmayan tüm satırları silin. Başka bir kullanıcı tarafından bahsedilen sözdizimi:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Olası bir sorunu var. "İLK 10 SEÇİN" sorgusu tablodaki her satır için yürütülür ve bu büyük bir performans artışı olabilir. Aynı sorguyu defalarca yapmaktan kaçınmak istersiniz.
Bu sözdizimi, orijinal SQL deyiminiz olarak listelediğinize göre çalışmalıdır:
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
insert into #nuke(Nuke) ...muhtemelen şöyle olmalıdır: insert into #nuke(NukeID) ...Ayrıca nuke adı kafa karıştırıcıdır çünkü bu satırları SİLMEMEYE çalışıyorsunuz. Nuke, muhtemelen silineceği gerçeğinden sonra adlandırılmıştır.
MS SQL kullanmayan kullanıcılar için gelecekteki referans.
PostgreSQL'de ORDER BYve LIMITyerine TOP.
DELETE FROM table
WHERE id NOT IN (SELECT id FROM table ORDER BY id LIMIT n);
MySQL - iyi ...
Hata - MySQL'in bu sürümü henüz 'LIMIT & IN / ALL / ANY / SOME alt sorgusunu' desteklemiyor
Henüz değil sanırım.
Sanal bir tablo kullanmanın bir IN cümlesi veya geçici tablodan çok daha iyi olacağını düşünüyorum.
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
Diğer tatları bilmiyorum ama MySQL DELETE LIMIT'e izin veriyor.
Bir şeyleri, tutmak istediğiniz n satır en altta olacak şekilde sıralayabilseydiniz, o zaman bir DELETE FROM tablecount-n yapabilirsiniz.
Düzenle
Oooo. Senin durumunda işe yaradığını varsayarak, Cory Foy'un cevabını daha çok sevdiğimi düşünüyorum . Karşılaştırıldığında yolum biraz hantal geliyor.
Bu gerçekten dile özgü olacak, ancak SQL sunucusu için muhtemelen aşağıdaki gibi bir şey kullanacağım.
declare @n int
SET @n = SELECT Count(*) FROM dTABLE;
DELETE TOP (@n - 10 ) FROM dTable
tam satır sayısı umurunuzda değilse, her zaman
DELETE TOP 90 PERCENT FROM dTABLE;
İşte böyle yaptım. Bu yöntem daha hızlı ve daha basittir:
OFFSET komutunu kullanarak MS SQL'deki veritabanı tablosundan üst n hariç tümünü sil
WITH CTE AS
(
SELECT ID
FROM dbo.TableName
ORDER BY ID DESC
OFFSET 11 ROWS
)
DELETE CTE;
IDSıralamak istediğiniz sütunla değiştirin . Saklamak OFFSETistediğiniz satır sayısının ardındaki sayıyı değiştirin . DESCVeya ASC- durumunuza uygun olanı seçin .
Daha iyi bir yol, İSTEDİĞİNİZ satırları başka bir tabloya eklemek, orijinal tabloyu bırakmak ve ardından yeni tabloyu eski tablo ile aynı ada sahip olacak şekilde yeniden adlandırmaktır.
TOPHer satır için ifadeyi çalıştırmaktan kaçınmam gereken bir numaram var . Biz birleştirebilirsiniz TOPile MAXalmak için MaxIdbiz devam etmek istiyorum. Sonra daha büyük olan her şeyi siliyoruz 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
Not: Uygun sonuçların sorgulandığından emin olmak için ORDER BYbeyan ederken kullanılması önemlidir MaxId.
DELETE FROM Table WHERE ID NOT IN (SELECT id FROM (SELECT TOP 10 ID FROM Table) AS x)MySQL'i geçici bir tablo oluşturmaya zorlamak için sorgu yazarak çözebileceğinizi unutmayın .