← Kursa Dön
📄 Text · 30 min

UNION ve UNION ALL

Giriş — Sorgu Sonuçlarını Birleştirme

UNION, iki veya daha fazla SELECT sorgusunun sonuçlarını dikey olarak birleştirir (alt alta). JOIN tabloları yatay (sütun ekleyerek) birleştirirken, UNION dikey (satır ekleyerek) birleştirir.

🎯 Analoji: İki farklı Excel sayfasındaki verileri tek bir sayfada alt alta yapıştırmak gibi. Sütun yapıları aynı olmalı.


UNION — Tekrar Elemeli Birleştirme

-- İstanbul ve Ankara'daki müşteriler (iki farklı sorgu birleştirilmiş)
SELECT first_name, last_name, city FROM customers WHERE city = 'İstanbul'
UNION
SELECT first_name, last_name, city FROM customers WHERE city = 'Ankara';
-- Tekrar eden satırlar elenir (DISTINCT gibi)

Kurallar:

  • Her SELECT aynı sayıda sütun döndürmeli

  • Sütunların veri tipleri uyumlu olmalı

  • Sütun isimleri ilk SELECT'ten alınır

  • Tekrar eden satırlar otomatik elenir (performans maliyeti var)


UNION ALL — Tekrar Elemesiz Birleştirme

SELECT first_name, city FROM customers WHERE city = 'İstanbul'
UNION ALL
SELECT first_name, city FROM customers WHERE city = 'İstanbul';
-- Aynı satırlar tekrar eder — eleme yapılmaz

💡 İpucu: Tekrar olmayacağını biliyorsan veya tekrar önemsizse UNION ALL kullan — UNION'dan çok daha hızlıdır çünkü sıralama/karşılaştırma yapmaz.


Pratik Kullanım Senaryoları

-- Farklı tablolardan gelen bildirimler
SELECT 'Sipariş' AS type, order_id AS id, order_date AS date FROM orders WHERE status = 'pending'
UNION ALL
SELECT 'Düşük Stok', product_id, NOW() FROM products WHERE stock_quantity < 10
UNION ALL
SELECT 'Yeni Müşteri', customer_id, registration_date FROM customers 
WHERE registration_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
ORDER BY date DESC;

-- FULL OUTER JOIN emülasyonu (B06'da gördük)
SELECT c.first_name, o.order_id
FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id
UNION
SELECT c.first_name, o.order_id
FROM customers c RIGHT JOIN orders o ON c.customer_id = o.customer_id;

ORDER BY ve LIMIT

-- UNION sonucuna ORDER BY uygula
SELECT product_name, price, 'Pahalı' AS segment FROM products WHERE price > 10000
UNION ALL
SELECT product_name, price, 'Ucuz' FROM products WHERE price < 500
ORDER BY price DESC    -- Tüm sonuca uygulanır
LIMIT 10;              -- Tüm sonuçtan ilk 10

⚠️ ORDER BY UNION'un sonuna yazılır ve tüm birleşik sonuca uygulanır.


Özet

  • UNION iki sorgu sonucunu birleştirir, tekrarları eler (yavaş)

  • UNION ALL tekrarları elemez (hızlı) — mümkünse bunu tercih et

  • Her SELECT aynı sütun sayısında olmalı

  • ORDER BY en sona yazılır, tüm sonuca uygulanır

  • Farklı tablolardan gelen verileri tek listede göstermek için idealdir