MySQL CONCAT_WS() ile NULL'a Takılmayan Birleştirme
Selamlar, bu yazımda MySQL'in görece sessiz kalan ama bir kez alıştığınızda elinizden düşmeyecek fonksiyonlarından biri olan CONCAT_WS()'e bakacağız. Bilhassa nullable kolonlardan ad-soyad ya da adres üreten herkesin başına gelmiştir: CONCAT() ile string birleştiriyorsunuz, ortadaki bir kolon NULL çıkıyor ve sonuç bir anda komple NULL oluyor. Hadi CONCAT_WS() bu kâbusu nasıl bitiriyor, bakalım.
CONCAT_WS() nedir?
İsmindeki WS, 'with separator' kısaltması; yani 'ayraçlı birleştir'. Fonksiyon iki ya da daha fazla string'i, ilk argüman olarak verdiğiniz ayraçla bir araya getiriyor. Asıl can alıcı özelliği ise şu: argümanlardan biri NULL ise onu sessizce atlar, geriye düzgün bir sonuç döndürür.
İmzası şöyle:
CONCAT_WS(ayrac, str1, str2, str3, ...)
Üç kuralı baştan aklınızda tutun: ayraç zorunlu, ayraç NULL olursa sonuç NULL döner ve gerisindeki NULL argümanlar atlanırken yerlerinde çift ayraç bırakmazlar. Son madde aslında en kıymetlisi - üreteceğiniz string'in cımbızla temizlenmesine gerek kalmıyor.
Temel kullanım
Üç hızlı örnekle ısınalım:
SELECT CONCAT_WS(', ', 'Ayşe', 'Yılmaz', 'İstanbul');
-- Sonuc: 'Ayşe, Yılmaz, İstanbul'
SELECT CONCAT_WS('-', '2026', '05', '08');
-- Sonuc: '2026-05-08'
SELECT CONCAT_WS(' | ', 'MySQL', '8.0', 'String Fonksiyonlari');
-- Sonuc: 'MySQL | 8.0 | String Fonksiyonlari'
Görüyorsunuz, ayraç tek karakter olmak zorunda değil; çok karakterli ayraç da çalışıyor. Bu sayede kayıt sınırlayıcı yerine ' - ' gibi okunabilir ayraçlar koyabiliyorsunuz.
CONCAT()'tan farkı: NULL muamelesi
İşin can damarı burası. Aynı veriyi iki fonksiyona verelim:
-- CONCAT() bir argüman bile NULL'sa sonucu NULL yapar
SELECT CONCAT('Ayşe', NULL, 'Yılmaz');
-- Sonuc: NULL
-- CONCAT_WS() NULL argümanı görmemiş gibi geçer
SELECT CONCAT_WS(' ', 'Ayşe', NULL, 'Yılmaz');
-- Sonuc: 'Ayşe Yılmaz'
Şahsi kanaatim, kolonun nullable olduğu her senaryoda CONCAT() kullanmak başınıza iş açar. COALESCE(col, '') ile bunu manuel çözmeye çalışırsanız bu sefer ortada boş ayraçlar belirir. CONCAT_WS() ikisini de tek hamlede halleder.
Nullable kolonlardan tam ad üretmek
Klasik senaryo: ikinci adı opsiyonel olan bir kişi tablosu. Hadi gerçek veriyle bakalım:
CREATE TABLE kisiler (
kisi_id INT PRIMARY KEY,
ad VARCHAR(50),
ikinci_ad VARCHAR(50),
soyad VARCHAR(50)
);
INSERT INTO kisiler VALUES
(1, 'Ayşe', 'Nur', 'Yılmaz'),
(2, 'Mehmet', NULL, 'Demir'),
(3, 'Zeynep', 'Su', NULL);
SELECT
kisi_id,
CONCAT_WS(' ', ad, ikinci_ad, soyad) AS tam_ad
FROM kisiler;
Sonuç:
| kisi_id | tam_ad |
|---|---|
| 1 | Ayşe Nur Yılmaz |
| 2 | Mehmet Demir |
| 3 | Zeynep Su |
İkinci satırda 'Mehmet Demir' gibi çift boşluklu bir çıktı yok; üçüncü satırda da sondan sarkan bir boşluk yok. Çünkü NULL argüman tamamen atlanıyor, yerine ayraç eklenmiyor.
Adresleri ve etiketli string'leri kurmak
Adres kolonları neredeyse her zaman kısmen NULL'dur. CONCAT_WS() burada da bir nimet:
SELECT
CONCAT_WS(', ', sokak, mahalle, ilce, sehir, posta_kodu) AS tam_adres
FROM adresler;
Eksik kolon hangisi olursa olsun, çıktı temiz kalır. Aynı mantığı raporlama için de kullanabilirsiniz:
SELECT
calisan_id,
CONCAT_WS(' - ', isim, COALESCE(departman, 'Atanmamis'), CONCAT('₺', FORMAT(maas, 0))) AS etiket
FROM calisanlar;
-- Ornek: 'Ayşe Yılmaz - Mühendislik - ₺85,000'
Burada COALESCE'i bilinçli olarak kullandım: departmanın NULL olmasını atlamak değil, 'Atanmamis' yazmak istiyorum. CONCAT_WS()'in NULL davranışı her zaman aradığınız şey olmayabilir, ikisini birlikte kullanmak şart.
Sık karşılaşılan tuzaklar
- Ayracın kendisinin NULL olması:
SELECT CONCAT_WS(NULL, 'a', 'b');çağrısıNULLdöner. Eğer ayracı bir alt sorgudan ya da değişkenden alıyorsanız,IFNULL(ayrac, ',')ile garanti altına almakta fayda var. - Boş string ile NULL'u karıştırmak:
''(boş string)NULLdeğildir;CONCAT_WS()bunu atlamaz, normal değer gibi araya ekler ve çift ayraç oluşur. Boş string'leri de atlamak istiyorsanızNULLIF(col, '')ile önceNULL'a çevirin. - Sayısal kolonlarda otomatik dönüşüm: Sayısal kolonlar string'e cast edilir, sorun yok; ama bilhassa
DECIMALkolonlarda biçim beklediğiniz gibi gelmeyebilir.FORMAT()ile önden biçimlendirmek sağlıklı. - GROUP_CONCAT() ile karıştırmak:
CONCAT_WS()aynı satırdaki kolonları birleştirir; birden fazla satırı tek string'e toplamak içinGROUP_CONCAT()lazım. İkisi farklı işlerdir.
Kapanış
CONCAT_WS() kâğıt üstünde küçük bir fonksiyon ama nullable kolonlarla çalışırken CONCAT() + IFNULL() kombinasyonunun sıkıntısını tamamen ortadan kaldırıyor. Bana sorarsanız, ad-soyad veya adres benzeri her birleştirmede varsayılanınız CONCAT_WS() olsun; ihtiyacınız değişirse CONCAT()'a düşersiniz, tersi acı verici. Bir sonraki yazıda görüşmek üzere.
