Kurs
Yinelenen kayıtlar, veri bütünlüğünü ve veritabanı performansını zedeleyebilen yaygın bir sorundur. Bu yinelenenleri kaldırmak; veri doğruluğunu korumak, depolamayı optimize etmek ve sorgu performansını iyileştirmek için kritik öneme sahiptir. Bu makalede, farklı kullanım senaryoları ve veritabanı yönetim sistemlerine göre uyarlanmış, SQL’de yinelenen satırları kaldırmaya yönelik çeşitli teknikleri inceleyeceğiz.
Başlarken, SQL kullanarak veri çıkarımı ve analizine dair temel bilgileri öğrenmek için DataCamp’in Introduction to SQL ve Learn SQL kurslarını almanızı özellikle tavsiye ederim. Ayrıca indirip kullanabileceğiniz SQL Basics Cheat Sheet en yaygın SQL fonksiyonlarının tamamını içerdiği için iyi bir başvuru kaynağıdır.
Kısa Özet
- Tabloyu değiştirmeden benzersiz satırlar getirmek için
SELECT DISTINCTveyaGROUP BYkullanın - Hangi yinelenenlerin kalıcı olarak kaldırılacağını hassas biçimde seçmek için CTE ile
ROW_NUMBER()veDELETEkullanın - Herhangi bir VTYS’de basit bir tekilleştirme için alt sorgu ile
DELETEkullanın (NOT IN/MIN()) - Büyük veri kümelerinde yinelenenleri güvenle toplu işlemek için geçici tablolar kullanın
- Yinelenmeleri önlemek için birincil anahtarlar, benzersiz kısıtlar ve doğru veritabanı normalizasyonu uygulayın
SQL'de Yinelenen Satırları Anlama
SQL’de yinelenen satırlar, bir tablodaki bazı veya tüm sütunlarda özdeş değerlere sahip kayıtları ifade eder. SQL’de yinelenen satırların yaygın nedenleri şunlardır:
- Birincil Anahtarların Eksikliği: Tablolarda tanımlı bir birincil anahtar veya benzersiz kısıt olmadığında, yinelenen verilerin eklenmesini engelleyecek bir mekanizma bulunmaz. Bu durum, bir tablo normalize edilmediğinde ve/veya geçişli bağımlılık sorunları olduğunda ortaya çıkabilir.
- Veri Entegrasyonu Sorunları: Farklı kaynaklardan veri birleştirilirken, hatalı birleştirmeler veya veri formatlarındaki tutarsızlıklar istemeden yinelenenlere yol açabilir.
- Manuel Veri Girişi Hataları: Aynı kaydın birden fazla kez girilmesi gibi insan hataları da yinelenen satırların bir başka yaygın nedenidir.
Makalenin geri kalanında SQL’de yinelenenlerin nasıl kaldırılacağını ele alacağız ve içeriği iki bölüme ayıracağız. İlk bölümde, bir rapor veya gösterge paneli için çektiğiniz verilerde yinelenenleri nasıl filtreleyeceğinizi; ikinci bölümde ise veritabanındaki yinelenenleri nasıl kaldıracağınızı inceleyeceğiz.
Yinelenen Satırlar Nasıl Belirlenir
Yinelenenleri kaldırmadan önce, hangi satırların yinelendiğini tespit edin. Birden fazla kez görünen satırları bulmak için GROUP BY ile HAVING COUNT(*) > 1 kullanın:
SELECT Name, COUNT(*) AS duplicate_count
FROM customers
GROUP BY Name
HAVING COUNT(*) > 1;
Bu sorgu, birden fazla görünen her Name’i ve kaç kez geçtiğini döndürür. Birden fazla sütuna genişletmek için aynı sütunları hem SELECT hem de GROUP BY ifadelerine ekleyebilirsiniz.
Her yinelenen grup içinde satırların sırasını belirten bir derecelendirme ile tüm satırları görmek için ROW_NUMBER() kullanın:
SELECT ID, Name,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY ID) AS row_num
FROM customers;
row_num > 1 olan satırlar yinelenendir. Belirledikten sonra, aşağıdaki bölümlerdeki uygun kaldırma yöntemini seçin.
Getirdiğiniz Verilerde Yinelenenleri Kaldırma Yöntemleri
SQL’de kayıtları çekerken yinelenenleri kaldırmanın farklı yöntemleri vardır. Her yöntem SQL Server, MySQL ve PostgreSQL gibi VTYS’lere göre değişebilir. Bu bölümde, her veritabanına özgü hususları da vurgulayarak getirilen verilerde yinelenenleri kaldırma yöntemlerine bakacağız. Unutmayın, bu yöntemler veriyi filtreler ve benzersiz kayıtları döndürür; alttaki tabloyu değiştirmez.
DISTINCT anahtar sözcüğünü kullanma
DISTINCT anahtar sözcüğü, benzersiz satırları getirmek için bir SELECT ifadesinde kullanılır. Yinelenenleri kaldırmak için DISTINCT sözdizimi MySQL, PostgreSQL ve SQL Server veritabanlarında benzerdir. Aşağıdaki sorgu, customers tablosundan benzersiz müşteri adlarını getirir.
SELECT DISTINCT Name
FROM customers;
GROUP BY ve toplu fonksiyonları kullanma
GROUP BY ifadesi, MAX(), MIN() veya COUNT() gibi diğer toplu fonksiyonlarla birleştirildiğinde, tablolardaki yinelenen kayıtları ayıklamaya yardımcı olabilir. GROUP BY ifadesi, hangilerinin tutulacağını seçerken diğer yinelenenlerin silinmesine imkân verir.
Diyelim ki yinelenen müşteri kayıtlarını silmek, ancak en yüksek ID’ye sahip olanı tutmak istiyorsunuz. Aşağıda gösterildiği gibi GROUP BY ifadesini MAX() fonksiyonuyla birlikte kullanırsınız.
-- Delete duplicate rows from the 'customers' table (aliased as c1)
DELETE c1
FROM customers c1
-- Find the maximum ID for each unique Name
JOIN (
SELECT Name, MAX(ID) AS MaxID
FROM customers
GROUP BY Name
) c2
-- Match rows based on 'Name' and keep the row with the maximum ID
ON c1.Name = c2.Name
AND c1.ID < c2.MaxID;
MySQL ve SQL Server, toplu fonksiyonlarla GROUP BY ve JOIN ifadesini kullanan yukarıdaki sözdizimini destekler.
Common Table Expressions (CTE) ile ROW_NUMBER() kullanma
ROW_NUMBER() fonksiyonunu bir Common Table Expression (CTE) ile birleştirerek, ölçütlerinize göre yinelenenleri filtreleyebilirsiniz. ROW_NUMBER fonksiyonu, PARTITION BY ve ORDER BY ile kullanıldığında her satıra benzersiz bir sıralı numara atar. Bu yöntem, gerekli ölçütleri karşılamayan satırları elemenize olanak tanır.
Aşağıdaki sorgu, yinelenenleri belirler ve ilk oluşum dışındaki tümünü kaldırır.
-- Common Table Expression (CTE) to rank rows based on 'Name'
WITH CTE AS (
SELECT ID, Name, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY ID ASC) AS RowNum
FROM customers
)
-- Select only the unique records where RowNum = 1
SELECT ID, Name
FROM CTE
WHERE RowNum = 1;
Bu yöntem, modern SQL Server, MySQL ve PostgreSQL sürümlerinde iyi çalışır. Daha büyük veri kümeleri veya daha karmaşık koşullar için faydalıdır; hangi yineleneni tutacağınızı tam olarak belirtmenize olanak tanır.
Self-JOIN kullanarak yinelenenleri kaldırma
Self-join, bir tabloyu kendisiyle karşılaştırmanızı sağlar; böylece belirli ölçütlere göre kayıtları kıyaslayarak yinelenen satırları belirlemede ve kaldırmada işe yarar. Aşağıdaki örnek, her isim için ilk kaydı tutarak daha yüksek ID’li satırı silmek üzere self-join kullanır.
-- Delete duplicate rows using self-join
DELETE c1
FROM customers c1
JOIN customers c2
ON c1.Name = c2.Name AND c1.ID > c2.ID;
Yukarıdaki yöntem SQL Server, MySQL ve PostgreSQL dahil başlıca veritabanlarında çalışır. Toplama fonksiyonları ve join’leri kullanarak veriyi filtrelemeyi öğrenmek için Intermediate SQL kursumuza göz atın.
Veritabanında Yinelenenleri Kaldırma Yöntemleri
Sorgularla yinelenen kayıtları kaldırabileceğiniz gibi, bunları veritabanından kalıcı olarak da silebilirsiniz. Bu yaklaşım, veri kalitesini korumak için önemlidir. Aşağıdaki yöntemler veritabanından yinelenenleri kaldırmak için kullanılır.
ROW_NUMBER() ve DELETE kullanma
ROW_NUMBER() fonksiyonu, tanımlı bir bölümlendirme içinde satırlara sıralı numara atar. DELETE ifadesiyle birlikte kullanıldığında, belirli sütunlara göre satırları derecelendirerek istenmeyen kayıtları kaldırmaya yardımcı olur. Bu yöntem, modern MySQL (8.0 ve üzeri), PostgreSQL ve SQL Server sürümleri için geçerlidir.
Diyelim ki Name sütununa göre yinelenen müşteri kayıtlarını kaldırmak, yalnızca ilk oluşumu (en küçük ID) tutmak istiyorsunuz:
-- Common Table Expression (CTE) to rank rows based on 'Name'
WITH CTE AS (
SELECT ID, Name, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY ID ASC) AS RowNum
FROM customers
)
-- Delete rows from the 'customers' table where the row number is greater than 1
DELETE FROM customers
WHERE ID IN (SELECT ID FROM CTE WHERE RowNum > 1);
Alt sorgu ile DELETE kullanma
Bazen, bir alt sorgu kullanan basit bir DELETE işlemi veritabanından yinelenenleri kaldırabilir. Bu yöntem, ROW_NUMBER()’ın bulunmadığı eski MySQL veya PostgreSQL sürümleri için uygundur.
Aşağıdaki sorgu, customers tablosunda her Name için en küçük ID olmayan satırları siler; böylece her benzersiz Name için en küçük ID’li satır korunur.
-- Delete rows from the 'customers' table
DELETE FROM customers
WHERE ID NOT IN (
-- Subquery to find the minimum ID for each unique Name
SELECT MIN(ID)
FROM customers
GROUP BY Name
);
HAVING ifadesiyle GROUP BY kullanma
Belirli sütunlarda yinelenen değerleri kontrol etmeniz gerektiğinde, GROUP BY ifadesini HAVING ile birleştirerek yinelenenleri tespit edebilirsiniz. Bu yöntem, verilen ölçütlere göre belirli satırların silinmesine olanak tanır. SQL Server, MySQL ve PostgreSQL ile uyumludur.
Aşağıdaki sorgular önce birden fazla görünen adları belirler, ardından her Name için en küçük ID’ye sahip satırı tutarak diğerlerini siler.
-- Step 1: Identify which Names have duplicates
SELECT Name, COUNT(*) AS duplicate_count
FROM customers
GROUP BY Name
HAVING COUNT(*) > 1;
-- Step 2: Delete duplicate rows, keeping the smallest ID for each Name
DELETE FROM customers
WHERE ID NOT IN (
SELECT MIN(ID)
FROM customers
GROUP BY Name
);
Toplu işleme için geçici tablolar kullanma
Geçici tablolar, büyük veri kümelerinde toplu işleme ve yinelenenleri kaldırma için etkilidir. Tek bir sorgunun performans sorunlarına yol açabileceği durumlarda faydalıdır. Aşağıdaki sorgu, her Name için en küçük ID’yi depolamak üzere bir geçici tablo oluşturur ve customers tablosunda ID’si temp_customers tablosunda olmayan satırları siler.
-- Create a temporary table with unique records
CREATE TEMPORARY TABLE temp_customers AS
SELECT MIN(ID) AS KeepID, Name
FROM customers
GROUP BY Name;
-- Delete duplicates not in the temporary table
DELETE FROM customers
WHERE ID NOT IN (SELECT KeepID FROM temp_customers);
-- Clean up
DROP TABLE temp_customers;
CREATE TEMPORARY TABLE kullanan yukarıdaki sözdizimi yalnızca MySQL ve PostgreSQL veritabanlarında desteklenir.
SQL Server'da Yinelenenleri Kaldırma
SQL Server, veritabanından yinelenen kayıtları kaldırmak için farklı yöntemler sunar. Bu yöntemler arasında INTO ile DISTINCT, ROW_NUMBER() ve geçici tablolar bulunur.
INTO ile DISTINCT kullanma
Benzersiz kayıtlara sahip yeni bir tablo oluşturmak için SELECT ifadesinde DISTINCT kullanabilirsiniz. Yeni tablonun istenen kayıtları içerdiğini doğruladıktan sonra eski tabloyu silebilirsiniz. Aşağıdaki örnek, customers tablosundaki benzersiz kayıtlardan unique_customers tablosunu oluşturur.
-- Select distinct rows from 'customers' and create a new table 'unique_customers'
SELECT DISTINCT *
INTO unique_customers
FROM customers;
-- Drop the original 'customers' table to remove it from the database
DROP TABLE customers;
-- Rename the 'unique_customers' table to 'customers' to replace the original table
EXEC sp_rename 'unique_customers', 'customers';
ROW_NUMBER() kullanma
SQL Server’da yinelenen kayıtları kaldırmak için ROW_NUMBER() fonksiyonunu da kullanabilirsiniz. CustomerName sütununa göre yinelenen satırlara sahip bir Customers tablonuz olduğunu ve her yinelenen grup için ilk oluşum dışındakileri silmek istediğinizi varsayalım.
-- Common Table Expression (CTE) to assign a row number to each customer
WITH CTE AS (
SELECT CustomerID, CustomerName, ROW_NUMBER() OVER (PARTITION BY CustomerName ORDER BY CustomerID ASC) AS RowNum
FROM Customers
)
-- Delete rows from the CTE
DELETE FROM CTE
WHERE RowNum > 1;
Geçici tablo kullanma
SQL Server CREATE TEMPORARY TABLE fonksiyonunu desteklemediğinden, SELECT INTO kullanırsınız. SQL Server’daki geçici tabloların adlarında önek olarak # bulunur.
-- Create a temporary table
SELECT MIN(CustomerID) AS ID, CustomerName
INTO #temp_customers
FROM customers
GROUP BY CustomerName;
-- Delete rows from the 'customers' table where the ID is not in the temporary table
DELETE FROM customers
WHERE CustomerID NOT IN (SELECT ID FROM #temp_customers);
-- Optionally drop the temporary table after use
DROP TABLE #temp_customers;
Tabloları birleştirme ve veri analizi becerilerinizi geliştirmek için SQL Server Fundamentals beceri yolumuzu denemenizi öneririm. SQL Server Developer kariyer yolu ise SQL Server kullanarak sorgularınızı yazma, sorun giderme ve optimize etme becerileri kazandırır.
Hızlı Referans: SQL Tekilleştirme Yöntemleri
Aşağıdaki tablo, bu makalede ele alınan tüm tekilleştirme yöntemlerini özetler; böylece durumunuza uygun yaklaşımı hızla seçebilirsiniz.
| Yöntem | Kullanım Durumu | Veriyi Değiştirir mi? | Veritabanı Desteği |
|---|---|---|---|
SELECT DISTINCT | Sorgu sonuçlarından benzersiz satırları getirme | Hayır | Tüm VTYS |
GROUP BY + toplular | Toplu değerlerle benzersiz satırları getirme | Hayır | Tüm VTYS |
ROW_NUMBER() + CTE (SELECT) | Sorgularda esnek yinelenen filtreleme | Hayır | SQL Server, MySQL 8.0+, PostgreSQL |
ROW_NUMBER() + CTE (DELETE) | İnce ayarlı kontrolle yinelenenleri kalıcı kaldırma | Evet | SQL Server, MySQL 8.0+, PostgreSQL |
DELETE ve alt sorgu | NOT IN / MIN() ile yinelenenleri kaldırma | Evet | Tüm VTYS |
Self-JOIN + DELETE | Satırları ikili karşılaştırarak yinelenenleri kaldırma | Evet | Tüm VTYS |
| Geçici tablo yaklaşımı | Büyük veri kümelerinde toplu işleme | Evet | MySQL, PostgreSQL (SQL Server için #temp) |
SELECT DISTINCT INTO | Tablonun temiz bir kopyasını oluşturma | Evet (tabloyu değiştirir) | SQL Server |
En İyi Uygulamalar
Yinelenen satırlar, veri kalitesini ve veritabanı performansını etkileyen yaygın bir sorundur. Veritabanınıza yinelenen kayıtların eklenmesini önlemek için aşağıdaki en iyi uygulamaları göz önünde bulundurun.
- Birincil Anahtarları Kullanın: Birincil anahtar sütunu, her kaydın benzersiz bilgi içermesini sağlayarak tabloya yinelenen değerlerin girmesini önler.
- Benzersiz Kısıtlar Uygulayın: Herhangi bir sütuna benzersiz kısıt uygulamak, e-posta adresleri veya telefon numaraları gibi birincil anahtar olmayan sütunlarda yinelenenlerin oluşmasını engeller.
- Doğru Veritabanı Tasarımı ve Normalizasyon: Etkili şema tasarımı ve veritabanı normalizasyonu, fazlalığı ve yinelenen veriyi azaltır. Bu yaklaşım, her kaydın ilgili tablolarda saklanmasını sağlar.
- Benzersiz İndeksler Kullanın: Tüm veri kümesi genelinde tablo düzeyinde kısıt gerekmeden, belirli sütun birleşimlerinin benzersiz olmasını sağlamak için benzersiz indeksler kullanın.
- Düzenli Veri Denetimleri: İş kurallarınıza göre potansiyel yinelenenleri belirlemek için düzenli olarak sorgular çalıştırarak veri denetimleri yapın.
Sonuç
Yinelenen satırları tespit etmek ve kaldırmak, veritabanı verimliliğini ve veri doğruluğunu korumak açısından önemlidir. Yanlışlıkla veri kaybını önlemek için değişiklik yapmadan önce her zaman verinizi yedeklemeniz en iyi uygulamadır.
Yetkin bir veri analisti olmakla ilgileniyorsanız, gerekli becerileri öğrenmek için Associate Data Analyst in SQL kariyer yolumuza göz atın. Reporting in SQL kursu ise SQL kullanarak profesyonel gösterge panelleri oluşturmayı öğrenmek isteyenler için uygundur. Son olarak, SQL’de veri analizi yetkinliğinizi kanıtlamak ve diğer veri profesyonelleri arasında öne çıkmak için SQL Associate Certification almanızı öneririm.
Sık Sorulan SQL Soruları
SQL veritabanlarında yinelenen satırlara ne sebep olur?
Yinelenen satırlar; hatalı veritabanı tasarımı, eksik birincil anahtarlar, birden çok kaynaktan veri entegrasyonu, manuel veri girişi hataları veya doğrulamanın düzgün uygulanmadığı veri taşıma süreçleri gibi çeşitli nedenlerle oluşabilir.
Birden fazla sütuna göre yinelenmeleri önleyebilir miyim?
Evet, birden çok sütunda bileşik anahtarlar veya benzersiz kısıtlar kullanarak benzersizliği zorunlu kılabilirsiniz. Bu, bu sütunlardaki değer birleşimlerinin benzersiz kalmasını sağlar.
DISTINCT anahtar sözcüğü yinelenen satırları nasıl kaldırır?
DISTINCT anahtar sözcüğünü kullanmak yalnızca sorgu sonuçlarındaki yinelenenleri kaldırır; alttaki veriyi değiştirmez.
Veritabanından yinelenen kayıtları kalıcı olarak silmek için hangi yöntemi kullanabilirim?
Veritabanından yinelenen satırları kalıcı olarak silmek için ROW_NUMBER() ile DELETE, alt sorgu ile DELETE, GROUP BY ve HAVING ifadesi ile, ayrıca toplu işlem için geçici tabloları kullanabilirsiniz.
Yinelenenler veritabanımın performansını etkileyebilir mi?
Evet, yinelenenler depolama maliyetlerini artırarak, sorguları yavaşlatarak ve veri analizini karmaşıklaştırarak performansı olumsuz etkileyebilir.
SQL'de yinelenen satırları nasıl bulurum?
Yinelenenleri bulmak için GROUP BY ile HAVING COUNT(*) > 1 kullanın. Örneğin: SELECT Name, COUNT(*) FROM customers GROUP BY Name HAVING COUNT(*) > 1; birden fazla görünen tüm adları döndürür. Ayrıca, her yinelenen grup içinde her satıra bir sıralama atamak için ROW_NUMBER() OVER (PARTITION BY Name ORDER BY ID) kullanabilirsiniz—sıralaması 1’den büyük olan satırlar yinelenendir.
Büyük bir SQL tablosundan yinelenenleri kaldırmanın en hızlı yolu nedir?
Büyük tablolar için geçici tablo yaklaşımını kullanın: benzersiz satırları SELECT DISTINCT veya GROUP BY ile bir geçici tabloya ekleyin, özgün tabloyu boşaltın (truncate), ardından temiz verileri geri yükleyin. Bu, milyonlarca kayıtta yavaş olabilen satır satır silmeden kaçınır. Alternatif olarak, hangi yinelenenin tutulacağını ince ayarla belirlemeniz gerektiğinde CTE ile ROW_NUMBER() verimlidir. Her zaman verinizi yedekleyin ve önce bir hazırlık ortamında test edin.
SQL'de yinelenen satırları nasıl bulurum?
Yinelenenleri bulmak için GROUP BY ile HAVING COUNT(*) > 1 kullanın. Örneğin: SELECT Name, COUNT(*) FROM customers GROUP BY Name HAVING COUNT(*) > 1; birden fazla görünen tüm adları döndürür. Ayrıca, her yinelenen grup içinde her satıra bir sıralama atamak için ROW_NUMBER() OVER (PARTITION BY Name ORDER BY ID) kullanabilirsiniz—sıralaması 1’den büyük olan satırlar yinelenendir.
