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 = 0filtresi 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 = 0filtresi 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_tarihkolonu 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 zamanDATEADDveya standart ISO tarih formatları (YYYYMMDD) kullanılmalıdır. - Eldeki Miktarı Yanlış Hesaplamak: Giriş ve çıkış hareketlerini ayırt etmeden sadece
sth_miktartoplamı 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.