Erp Asistanı Erp Asistanı
Mikro SQL

Mikro Ölü Stok Raporu SQL: Hareketsiz Ürünleri Listeleme

7 dk okuma Erp Asistanı
Mikro Ölü Stok Raporu SQL: Hareketsiz Ürünleri Listeleme

Depolarda bekleyen, aylardır hiçbir satış veya transfer işlemi görmeyen atıl stoklar, işletmeler için ciddi bir finansal yük oluşturur. Mikro ERP içerisinde bu ürünleri tespit etmek, stok maliyetlerini düşürmek ve depo alanını optimize etmek için hayati önem taşır. Bu rehberde, son N ayda hiçbir hareket görmemiş (ölü) stokları, eldeki güncel miktarları ve son hareket tarihlerini de içerecek şekilde SQL Server (T-SQL) üzerinden nasıl raporlayacağınızı adım adım göstereceğiz.

Sorgularımızın tamamı Mikro v16 ve v17 veritabanı yapılarıyla tam uyumludur. Mikro veritabanındaki stok ve hareket mantığını daha iyi kavramak için öncelikle Mikro tablo yapısı rehberi yazımıza göz atabilirsiniz. Ayrıca genel stok raporlama yöntemleri için Mikro stok depo raporu sql makalemiz de size yardımcı olacaktır.

Mikro Veritabanında Hareketsizlik Analizi Nasıl Yapılır?

Bir stoğun hareketsiz olduğunu belirlemek için iki temel veriye ihtiyacımız vardır: Stok kartının kendisi (STOKLAR) ve bu karta bağlı geçmiş hareketler (STOK_HAREKETLERI).

Eğer bir stok kartı için belirli bir tarih aralığında (örneğin son 6 ayda) hiçbir hareket kaydı oluşmamışsa, bu stok hareketsiz kabul edilir. SQL'de bu kontrolü yapmanın en performanslı yolu NOT EXISTS desenini kullanmaktır. LEFT JOIN kullanıp NULL kontrolü yapmak büyük veritabanlarında ciddi performans kayıplarına yol açabilir. NOT EXISTS ise ilgili tarih aralığında ilk eşleşen kaydı bulduğu anda aramayı keserek çok daha hızlı sonuç üretir.

Kullanılacak Tablolar ve Kolonlar

Sorgularımızda kullanacağımız Mikro tabloları ve kritik kolonları aşağıdaki tabloda özetlenmiştir:

Tablo Adı Kolon Adı Veri Tipi Açıklama
STOKLAR sto_kod nvarchar(25) Stok kartı benzersiz kodu (PK)
STOKLAR sto_isim nvarchar(127) Stok adı
STOKLAR sto_birim1_ad nvarchar(10) Stok ana birimi
STOKLAR sto_iptal bit Kartın iptal durumu (0: Aktif, 1: İptal)
STOKLAR sto_hidden bit Kartın gizlilik durumu (0: Görünür, 1: Gizli)
STOK_HAREKETLERI sth_stok_kod nvarchar(25) Harekete konu olan stok kodu
STOK_HAREKETLERI sth_tarih datetime Hareketin gerçekleştiği tarih
STOK_HAREKETLERI sth_tip tinyint Giriş/Çıkış yönü (0: Giriş, 1: Çıkış)
STOK_HAREKETLERI sth_miktar float Hareket miktarı
STOK_HAREKETLERI sth_iptal bit Hareketin iptal durumu (0: Aktif, 1: İptal)

1. Son 6 Ayda Hiç Hareket Görmeyen Stoklar

Bu temel sorgu, son 6 ay içerisinde STOK_HAREKETLERI tablosunda hiçbir aktif kaydı bulunmayan stok kartlarını listeler. İptal edilmiş stok kartları ve gizli tanımlar rapora dahil edilmez.

SELECT s.sto_kod, s.sto_isim, s.sto_birim1_ad
FROM STOKLAR s
WHERE s.sto_iptal = 0 
  AND s.sto_hidden = 0
  AND NOT EXISTS (
      SELECT 1
      FROM STOK_HAREKETLERI sh
      WHERE sh.sth_stok_kod = s.sto_kod
        AND sh.sth_iptal = 0
        AND sh.sth_tarih >= DATEADD(month, -6, GETDATE())
  )
ORDER BY s.sto_kod;

2. Son Hareket Tarihi ve Eldeki Miktar ile Ölü Stok Raporu

Sadece hareketsiz stokları listelemek yetmez; bu ürünlerin depomuzda ne kadar beklediğini (eldeki miktar) ve en son ne zaman işlem gördüğünü de bilmemiz gerekir. Aşağıdaki sorgu, son 6 aydır hareketsiz olan ürünlerin son hareket tarihini (MAX(sth_tarih)) ve net eldeki miktarını hesaplar.

SELECT s.sto_kod, s.sto_isim, s.sto_birim1_ad,
       (SELECT MAX(sh_t.sth_tarih)
        FROM STOK_HAREKETLERI sh_t
        WHERE sh_t.sth_stok_kod = s.sto_kod 
          AND sh_t.sth_iptal = 0) AS SonHareketTarihi,
       ISNULL((SELECT SUM(CASE WHEN sh_m.sth_tip = 0 THEN sh_m.sth_miktar ELSE -sh_m.sth_miktar END)
               FROM STOK_HAREKETLERI sh_m
               WHERE sh_m.sth_stok_kod = s.sto_kod 
                 AND sh_m.sth_iptal = 0), 0) AS EldekiMiktar
FROM STOKLAR s
WHERE s.sto_iptal = 0 
  AND s.sto_hidden = 0
  AND NOT EXISTS (
      SELECT 1
      FROM STOK_HAREKETLERI sh
      WHERE sh.sth_stok_kod = s.sto_kod
        AND sh.sth_iptal = 0
        AND sh.sth_tarih >= DATEADD(month, -6, GETDATE())
  )
ORDER BY EldekiMiktar DESC;

3. Sadece Elde Stok Olan ve 12 Aydır Hareketsiz Olan Ürünler

Eğer depoda fiziksel olarak bulunmayan (miktarı sıfır veya eksi olan) ürünleri rapordan ayıklamak istiyorsanız, CROSS APPLY yardımıyla eldeki miktarı hesaplayıp sadece EldekiMiktar > 0 olan ve son 1 yıldır hiç hareket görmemiş ürünleri filtreleyebilirsiniz. Bu, gerçek anlamda depoda yer kaplayan ölü stokları gösterir.

SELECT s.sto_kod, s.sto_isim, s.sto_birim1_ad,
       (SELECT MAX(sh_t.sth_tarih)
        FROM STOK_HAREKETLERI sh_t
        WHERE sh_t.sth_stok_kod = s.sto_kod 
          AND sh_t.sth_iptal = 0) AS SonHareketTarihi,
       t.EldekiMiktar
FROM STOKLAR s
CROSS APPLY (
    SELECT ISNULL(SUM(CASE WHEN sh_m.sth_tip = 0 THEN sh_m.sth_miktar ELSE -sh_m.sth_miktar END), 0) AS EldekiMiktar
    FROM STOK_HAREKETLERI sh_m
    WHERE sh_m.sth_stok_kod = s.sto_kod 
      AND sh_m.sth_iptal = 0
) t
WHERE s.sto_iptal = 0 
  AND s.sto_hidden = 0
  AND t.EldekiMiktar > 0
  AND NOT EXISTS (
      SELECT 1
      FROM STOK_HAREKETLERI sh
      WHERE sh.sth_stok_kod = s.sto_kod
        AND sh.sth_iptal = 0
        AND sh.sth_tarih >= DATEADD(month, -12, GETDATE())
  )
ORDER BY t.EldekiMiktar DESC;

Benzer mantıkla çalışan diğer hazır sorgu örnekleri için Mikro hazır SQL sorguları içeriğimizi de inceleyebilirsiniz.

Sık yapılan hatalar

  • İptal Filtresini Unutmak: sth_iptal = 0 filtresi eklenmediğinde, iptal edilmiş eski evraklar hareket gibi algılanır ve aslında ölü olan bir stok canlıymış gibi görünebilir.
  • Gizli Kartları Filtrelememek: sto_hidden = 0 filtresi kullanılmadığında, sistemde kullanımdan kaldırılmış ve gizlenmiş eski stok kartları da raporda listelenerek kalabalık yaratır.
  • Tarih Fonksiyonlarında Tip Hatası: sth_tarih kolonu datetime tipindedir. Bu kolonu integer veya uyumsuz string formatlarıyla doğrudan karşılaştırmaya çalışmak SQL Server tarafında örtük dönüşüm (implicit conversion) hatalarına ve performans kayıplarına yol açar. Tarih filtrelerinde her zaman DATEADD veya standart ISO tarih formatları (YYYYMMDD) kullanılmalıdır.
  • Eldeki Miktarı Yanlış Hesaplamak: Giriş ve çıkış hareketlerini ayırt etmeden sadece sth_miktar toplamı almak büyük bir hatadır. Giriş hareketleri (sth_tip = 0) artı, çıkış hareketleri (sth_tip = 1) eksi yönlü işleme sokulmalıdır.

Sık sorulanlar

Sorguda son hareket tarihinin NULL gelmesi ne anlama gelir?
Eğer bir stok kartının son hareket tarihi NULL ise, o ürün kartı açıldığından beri Mikro veritabanında hiçbir stok hareketi (fatura, irsaliye, depo transferi vb.) görmemiş demektir. Bu ürünler en öncelikli ölü stok adaylarıdır.

Bu sorguları belirli bir depoya göre nasıl filtreleyebilirim?
Eldeki miktar hesaplamasında depo bazlı filtreleme yapmak için STOK_HAREKETLERI tablosundaki sth_giris_depo_no ve sth_cikis_depo_no kolonlarını kullanmanız gerekir. Depo bazlı detaylı raporlama mantığı için Mikro stok depo raporu sql yazımızı inceleyebilirsiniz.

Sorgu performansını artırmak için ne yapabilirim?
STOK_HAREKETLERI tablosunda sth_stok_kod, sth_tarih ve sth_iptal kolonlarını içeren indekslerin (index) tanımlı olduğundan emin olun. NOT EXISTS yapısı bu indeksleri kullanarak milisaniyeler içinde sonuç verecektir.


Deponuzdaki hareketsiz ürünleri tespit etmek, nakit akışınızı doğru yönetmenin ilk adımıdır. Erp Asistanı ile Mikro veritabanınızdaki tüm verileri karmaşık SQL kodları yazmak zorunda kalmadan, doğrudan doğal dille sorgulayabilirsiniz.

Erp Asistanı'na ücretsiz üye olun, raporlarınızı saniyeler içinde hazırlayın →

Mikro'da SQL ve raporu konuşarak alın

Türkçe sorunuzu yazın, şemanıza uygun çalışan SQL'i ya da hazır uygulamanızı saniyeler içinde alın. Kredi kartı gerekmez.