Netsis Stok ABC Analizi SQL: TBLSTHAR ile Pareto Ciro Raporu
Netsis TBLSTHAR tablosundan satış ve iade hareketlerini ayıklayarak ürün bazlı kümülatif ciro ve ABC sınıflandırması (Pareto) yapan T-SQL rehberi.
Erp Asistanı
Editör ekibi
6 dk okuma
İçindekiler
Stok yönetiminde 80/20 (Pareto) kuralı, toplam cironun yaklaşık %80'inin stok kalemlerinizin yalnızca %20'si tarafından üretildiğini söyler. Bu kurala dayanan ABC analizi; işletmelerin tedarik önceliklerini belirlemesini, depo yerleşimini optimize etmesini ve sermaye bağlanan ölü stokları tespit etmesini sağlar. Netsis ERP üzerinde bu analizi doğru kurabilmek için stok hareketlerinin tutulduğu ana tablo olan TBLSTHAR üzerindeki hareket tiplerini ve iade yönlerini doğru filtrelemek şarttır.
Birçok ERP kullanıcısı, satış faturalarını toplarken yalnızca çıkış (STHAR_GCKOD = 'C') hareketlerini dikkate alır. Ancak satış iadeleri (STHAR_GCKOD = 'G') net cirodan düşülmediğinde, yüksek tutarlı fakat sürekli iade dönen sorunlu ürünler yanlışlıkla en değerli ürün grubu olan "A Grubu" içinde listelenir. Bu yazıda, Netsis tablo yapısı kurallarına uygun olarak T-SQL window fonksiyonları ile dinamik ve iade düzeltmeli ABC sınıflandırması yapıyoruz.
Netsis TBLSTHAR Tablosunda Satış ve Net Ciro Mantığı
Netsis mimarisinde fatura ve irsaliye satırları doğrudan TBLSTHAR tablosunda saklanır. Fatura satırlarında hazır bir "toplam satır tutarı" kolonu bulunmaz. Net satır tutarı, hareket miktarı (STHAR_GCMIK) ile KDV/iskonto sonrası net birim fiyatın (STHAR_NF) çarpımıyla elde edilir. Brüt liste fiyatı olan STHAR_BF kullanılırsa iskontolar yansımayacağı için ciro şişkin görünür.
Satış cirosunu doğru hesaplamak için iki temel alana odaklanmak gerekir:
STHAR_FTIRSIP(Belge Tipi): Satış faturaları'1'değeriyle tutulur. Faturalaşmamış irsaliyeler de dahil edilecekse'3'kodu eklenir. Ancak dönemsel kesinleşmiş ciro raporlarında mükerrerliği önlemek adına sadece fatura satırları ('1') veya irsaliye durumu netleştirilerek sorgulanmalıdır.STHAR_GCKOD(Giriş/Çıkış Yönü): Normal satış hareketleri depodan çıkış olduğu için'C'kodludur. Müşteriden gelen satış iadesi faturaları ise stoğa giriş oluşturduğu içinSTHAR_FTIRSIP = '1'olduğu haldeSTHAR_GCKOD = 'G'olarak işaretlenir. Bu sebeple net ciro bulunurken'G'hareketleri eksi olarak toplanmalıdır.
Belge Tipi (STHAR_FTIRSIP) |
Hareket Yönü (STHAR_GCKOD) |
İşlem Anlamı | Ciroya Etkisi |
|---|---|---|---|
1 (Satış Faturası) |
C (Çıkış) |
Normal Müşteri Satışı | + Pozitif Ciro |
1 (Satış Faturası) |
G (Giriş) |
Satış İade Faturası | - Negatif Ciro (Düşülmeli) |
2 (Alış Faturası) |
G (Giriş) |
Tedarikçi Alımı | Ciroya Katılmaz (Maliyet) |
8 / 9 (Depo Transferi) |
G / C |
Şube/Depo Transferi | Ciroya Katılmaz |
ABC Sınıfları ve Eşik Değerleri
Pareto analizinde ürünler kümülatif ciro paylarına göre üç ana kategoriye ayrılır:
- A Grubu (Kritik Stoklar): Kümülatif cironun %0 ile %80 arasını oluşturan en değerli ürünlerdir. Stoksuz kalma maliyeti en yüksek gruptur; sipariş periyotları sıkı takip edilir.
- B Grubu (Orta Öncelikli Stoklar): Kümülatif cironun %80 ile %95 arasını oluşturan ürünlerdir. Dengeli bir stok takip politikası uygulanır.
- C Grubu (Düşük Öncelikli / Kuyruk Stoklar): Kümülatif cironun son %5'lik dilimini (%95 - %100) oluşturan ürünlerdir. Genellikle ürün çeşidinin çoğunluğunu oluştururlar ancak sermaye getirileri düşüktür.
Aşağıdaki sorgularda bu eşik değerleri dinamik olarak hesaplanmaktadır.
1. Yanıltıcı Ciro Sorgusu (İadeleri Yok Sayan Hatalı Yaklaşım)
Aşağıdaki sorgu, sahada en sık yapılan hatayı göstermektedir. İadeler hesaba katılmadığı için ürünlerin brüt satışı ciro sanılır:
-- HATALI YAKLAŞIM: İadeler düşülmeden sadece çıkışlar toplanıyor
SELECT
STOK_KODU,
SUM(STHAR_GCMIK * STHAR_NF) AS HataliBrutCiro
FROM TBLSTHAR
WHERE STHAR_FTIRSIP = '1'
AND STHAR_GCKOD = 'C'
AND SUBE_KODU = 0
AND STHAR_TARIH >= '20260101' AND STHAR_TARIH < '20270101'
GROUP BY STOK_KODU
ORDER BY HataliBrutCiro DESC;
2. Doğru Net Ciro Hesaplama Sorgusu (İade Düşümlü)
Doğru net ciro için CASE yapısı ile çıkışlar pozitif, girişler negatif toplanır. Ayrıntılı stok hareket mantığı için Netsis stok hareketleri rehberine göz atabilirsiniz.
-- DOĞRU HESAPLAMA: Satış faturalarında G=İade (-), C=Satış (+)
SELECT
s.STOK_KODU,
MAX(s.STOK_ADI) AS STOK_ADI,
SUM(CASE
WHEN h.STHAR_GCKOD = 'C' THEN h.STHAR_GCMIK * h.STHAR_NF
WHEN h.STHAR_GCKOD = 'G' THEN -(h.STHAR_GCMIK * h.STHAR_NF)
ELSE 0
END) AS NetCiro,
SUM(CASE
WHEN h.STHAR_GCKOD = 'C' THEN h.STHAR_GCMIK
WHEN h.STHAR_GCKOD = 'G' THEN -h.STHAR_GCMIK
ELSE 0
END) AS NetSatismiktari
FROM TBLSTHAR h
INNER JOIN TBLSTSABIT s ON s.STOK_KODU = h.STOK_KODU
WHERE h.STHAR_FTIRSIP = '1'
AND h.SUBE_KODU = 0
AND h.STHAR_TARIH >= '20260101' AND h.STHAR_TARIH < '20270101'
GROUP BY s.STOK_KODU
HAVING SUM(CASE WHEN h.STHAR_GCKOD = 'C' THEN h.STHAR_GCMIK * h.STHAR_NF WHEN h.STHAR_GCKOD = 'G' THEN -(h.STHAR_GCMIK * h.STHAR_NF) ELSE 0 END) > 0
ORDER BY NetCiro DESC;
3. Tam Kapsamlı Stok ABC Analizi (Pareto SQL)
T-SQL window fonksiyonları (SUM() OVER) kullanılarak kümülatif ciro ve kümülatif yüzde hesaplanır; ardından her ürün A, B veya C sınıfına atanır:
WITH UrunNetCiro AS (
SELECT
h.STOK_KODU,
MAX(s.STOK_ADI) AS STOK_ADI,
MAX(s.GRUP_KODU) AS GRUP_KODU,
SUM(CASE
WHEN h.STHAR_GCKOD = 'C' THEN h.STHAR_GCMIK * h.STHAR_NF
WHEN h.STHAR_GCKOD = 'G' THEN -(h.STHAR_GCMIK * h.STHAR_NF)
ELSE 0
END) AS NetCiro
FROM TBLSTHAR h
INNER JOIN TBLSTSABIT s ON s.STOK_KODU = h.STOK_KODU
WHERE h.STHAR_FTIRSIP = '1'
AND h.SUBE_KODU = 0
AND h.STHAR_TARIH >= '20260101' AND h.STHAR_TARIH < '20270101'
GROUP BY h.STOK_KODU
HAVING SUM(CASE WHEN h.STHAR_GCKOD = 'C' THEN h.STHAR_GCMIK * h.STHAR_NF WHEN h.STHAR_GCKOD = 'G' THEN -(h.STHAR_GCMIK * h.STHAR_NF) ELSE 0 END) > 0
),
KumulatifHesap AS (
SELECT
STOK_KODU,
STOK_ADI,
GRUP_KODU,
NetCiro,
SUM(NetCiro) OVER (ORDER BY NetCiro DESC ROWS UNBOUNDED PRECEDING) AS KumulatifCiro,
SUM(NetCiro) OVER () AS GenelToplamCiro
FROM UrunNetCiro
),
ParetoOran AS (
SELECT
STOK_KODU,
STOK_ADI,
GRUP_KODU,
NetCiro,
KumulatifCiro,
GenelToplamCiro,
CAST((NetCiro / NULLIF(GenelToplamCiro, 0)) * 100.0 AS DECIMAL(18, 2)) AS CiroPayYuzde,
CAST((KumulatifCiro / NULLIF(GenelToplamCiro, 0)) * 100.0 AS DECIMAL(18, 2)) AS KumulatifYuzde
FROM KumulatifHesap
)
SELECT
STOK_KODU,
STOK_ADI,
GRUP_KODU,
NetCiro,
CiroPayYuzde,
KumulatifYuzde,
CASE
WHEN KumulatifYuzde <= 80.00 THEN 'A'
WHEN KumulatifYuzde <= 95.00 THEN 'B'
ELSE 'C'
END AS ABC_SINIFI
FROM ParetoOran
ORDER BY NetCiro DESC;
4. ABC Sınıfları Dağılım Özeti (Yönetici Raporu)
Yukarıdaki sınıflandırmanın ardından sınıfların genel ciro ve ürün adedi dağılımını gösteren özet sorgu:
WITH UrunNetCiro AS (
SELECT
h.STOK_KODU,
SUM(CASE
WHEN h.STHAR_GCKOD = 'C' THEN h.STHAR_GCMIK * h.STHAR_NF
WHEN h.STHAR_GCKOD = 'G' THEN -(h.STHAR_GCMIK * h.STHAR_NF)
ELSE 0
END) AS NetCiro
FROM TBLSTHAR h
WHERE h.STHAR_FTIRSIP = '1'
AND h.SUBE_KODU = 0
AND h.STHAR_TARIH >= '20260101' AND h.STHAR_TARIH < '20270101'
GROUP BY h.STOK_KODU
HAVING SUM(CASE WHEN h.STHAR_GCKOD = 'C' THEN h.STHAR_GCMIK * h.STHAR_NF WHEN h.STHAR_GCKOD = 'G' THEN -(h.STHAR_GCMIK * h.STHAR_NF) ELSE 0 END) > 0
),
KumulatifHesap AS (
SELECT
STOK_KODU,
NetCiro,
CAST((SUM(NetCiro) OVER (ORDER BY NetCiro DESC ROWS UNBOUNDED PRECEDING) /
NULLIF(SUM(NetCiro) OVER (), 0)) * 100.0 AS DECIMAL(18, 2)) AS KumulatifYuzde
FROM UrunNetCiro
),
Siniflandirilmis AS (
SELECT
STOK_KODU,
NetCiro,
CASE
WHEN KumulatifYuzde <= 80.00 THEN 'A'
WHEN KumulatifYuzde <= 95.00 THEN 'B'
ELSE 'C'
END AS ABC_SINIFI
FROM KumulatifHesap
)
SELECT
ABC_SINIFI,
COUNT(STOK_KODU) AS ToplamUrunSayisi,
SUM(NetCiro) AS SinifToplamCiro,
CAST((SUM(NetCiro) / (SELECT SUM(NetCiro) FROM Siniflandirilmis)) * 100.0 AS DECIMAL(18, 2)) AS CiroOrani
FROM Siniflandirilmis
GROUP BY ABC_SINIFI
ORDER BY ABC_SINIFI;
5. Parametreli ve Depo Filtreli ABC Analizi
Analizi belirli bir depo veya tarih aralığına göre çalıştırmak istediğinizde aşağıdaki parametrik şablonu kullanabilirsiniz. Rapor hatalarından kaçınmak için ERP raporlamada 10 hata yazımızı inceleyebilirsiniz.
DECLARE @BasTarih DATETIME = '2026-01-01';
DECLARE @BitTarih DATETIME = '2026-12-31 23:59:59';
DECLARE @SubeKodu SMALLINT = 0;
DECLARE @DepoKodu SMALLINT = 1; -- Belirli bir depo filtrelenmek istenirse
WITH DepoCiro AS (
SELECT
h.STOK_KODU,
MAX(s.STOK_ADI) AS STOK_ADI,
SUM(CASE
WHEN h.STHAR_GCKOD = 'C' THEN h.STHAR_GCMIK * h.STHAR_NF
WHEN h.STHAR_GCKOD = 'G' THEN -(h.STHAR_GCMIK * h.STHAR_NF)
ELSE 0
END) AS NetCiro
FROM TBLSTHAR h
INNER JOIN TBLSTSABIT s ON s.STOK_KODU = h.STOK_KODU
WHERE h.STHAR_FTIRSIP = '1'
AND h.SUBE_KODU = @SubeKodu
AND (@DepoKodu IS NULL OR h.DEPO_KODU = @DepoKodu)
AND h.STHAR_TARIH BETWEEN @BasTarih AND @BitTarih
GROUP BY h.STOK_KODU
HAVING SUM(CASE WHEN h.STHAR_GCKOD = 'C' THEN h.STHAR_GCMIK * h.STHAR_NF WHEN h.STHAR_GCKOD = 'G' THEN -(h.STHAR_GCMIK * h.STHAR_NF) ELSE 0 END) > 0
),
SiraliListe AS (
SELECT
STOK_KODU,
STOK_ADI,
NetCiro,
CAST((SUM(NetCiro) OVER (ORDER BY NetCiro DESC ROWS UNBOUNDED PRECEDING) /
NULLIF(SUM(NetCiro) OVER (), 0)) * 100.0 AS DECIMAL(18, 2)) AS KumulatifYuzde
FROM DepoCiro
)
SELECT
STOK_KODU,
STOK_ADI,
NetCiro,
KumulatifYuzde,
CASE
WHEN KumulatifYuzde <= 80.00 THEN 'A (Yüksek Öncelik)'
WHEN KumulatifYuzde <= 95.00 THEN 'B (Orta Öncelik)'
ELSE 'C (Düşük Öncelik)'
END AS Segment
FROM SiraliListe
ORDER BY NetCiro DESC;
Sık yapılan hatalar
- İade hareketlerini yok saymak: Satış faturaları (
STHAR_FTIRSIP = '1') filtrelendiğindeSTHAR_GCKOD = 'G'satırları düşülmezse, iadesi yüksek ürünler haksız yere A sınıfına girer. STHAR_BFile hesaplama yapmak: Liste fiyatı iskonto içermez. Satış cirosu hesaplanırken net fiyat olanSTHAR_NFkullanılmalıdır.- Şube filtresi koymamak: Çok şubeli Netsis kurulumlarında
SUBE_KODUfiltresi verilmezse farklı şubelerin verileri birbirine karışır. - İrsaliye ve faturayı mükerrer toplamak:
STHAR_FTIRSIP IN ('1', '3')filtresi kullanılırken faturalanmış irsaliyelerin tekrar sayılmaması için dikkat edilmelidir. Dönem cirosunda fatura bazlı ('1') gitmek en güvenli yoldur. - Sıfır ve negatif cirolu ürünleri kümülatife dahil etmek: İadesi satışından fazla olan (net cirosu eksiye düşen) veya hiç satışı olmayan ürünler
HAVING NetCiro > 0filtresiyle Pareto tabanından çıkarılmalıdır.
Sık sorulanlar
ABC analizini ciro yerine miktar bazında yapabilir miyim? Evet. Sorgulardaki h.STHAR_GCMIK * h.STHAR_NF hesaplaması yerine doğrudan h.STHAR_GCMIK miktarını kullanarak miktar bazlı hareket yoğunluğu Pareto raporu elde edebilirsiniz.
ABC sınıf yüzdelerini (%80 / %15 / %5) değiştirebilir miyim? Evet. Sektörünüze veya işletme dinamiklerinize göre CASE WHEN KumulatifYuzde <= 70.00 THEN 'A' gibi eşik değerlerini dilediğiniz gibi güncelleyebilirsiniz.
Dövizli satışlar bu sorguda nasıl değerlendirilir? Bu sorgular yerel para birimi (TL) bazındaki net fiyatı (STHAR_NF) baz alır. Rapor döviz cinsinden alınacaksa STHAR_DOVTIP ve STHAR_DOVFIAT kolonları dikkate alınmalıdır.
Netsis veritabanınızda doğru filtrelenmiş SQL sorguları kurmak stok yönetiminizi güçlendirir. İhtiyacınız olan tüm stok, cari ve ciro analizlerini doğal dille yazarak saniyeler içinde almak için Erp Asistanı'nı hemen deneyebilirsiniz.
Netsis'te 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.