2016-04-11 19 views
2

Son ürün, yeni ürün için Ayarlanmış Günlük Hacmi hesaplamaktır.T-SQL Sorguyu Hesaplamak Stokta

Önce bir ürün stokta kalmadığında bunu bilmem gerekiyor, bu beni öldürüyor. Bir OnHandAfter sıfırdır

TransaDate ItemCode TransQty OnHandBefore OnHandAfter 
1/1/2016 xyz-125  -5    20    15 
1/4/2016 xyz-126  -4    15    11 
1/7/2016 xyz-127  -2    11    9 
1/8/2016 xyz-128  -6    9    3 
1/8/2016 xyz-129  -3    3    0 
1/13/2016 xyz-130  20    0    20 
1/13/2016 xyz-131  -4    20    16 
1/13/2016 xyz-132  -10    16    6 
1/18/2016 xyz-133  -6    6    0 
1/23/2016 xyz-134  5    0    5 
1/26/2016 xyz-135  -5    5    0 
1/28/2016 xyz-136  20    0    20 
1/28/2016 xyz-137  -4    20    16 

Herzaman O bütün gün stokta öğeyi düşünebilirsiniz. İdeal olarak, her ikisi de kısmi satış olduğu için 0 Önce veya Sonra olan günleri görmezden gelirim. Ama benim için önemli ve zor kısmı, bir ürün stoktan çıktıktan sonraki gün. Giriş yok, bu yüzden düz bir katılım yapamıyorum. Bu nedenle yukarıdaki örnekte, 27. listelenmemiş olsa bile, eşya 26 ve 27'de stokta kalmamıştır. Toplamda bu örnek Jan 8,9,10,11,12,13 stokta olduğunu gösterir, sonra 20 hisse senedi alırız, o zaman Jan 18,19,20,21,22,23,26,27,28 de stoklar tükendi.

Toplam satılır: 49
günlük ortalama hacmi: 49/31 = 1.58
Gün dışı Stok: 15
Arındırılmış Günlük Hacim: yana 49/(31-15) = 3,06

bir kayıtlar hiçbir satış yapılmadan günler için yapılır. Sanırım aralıktaki tüm tarihleri ​​içeren türetilmiş bir tablo (veya bunun gibi bir şey) oluşturmam gerekiyor. Daha karmaşık hale getirmek için tarih aralığı her bir öğe için dinamik olacak. Öğemizin sitemizde ilk 30 gün içinde kaç tane satıldığını bilmek istiyorum. Yani başlangıç ​​tarihi her öğe için dinamik olmalı.

Diğer ana tablo öğe tablosudur. Şimdiye kadar sahip olduğum şeyi gösterirdim, ama hiç yardım bilmezdim. Bunu yapmanın en iyi yolu olarak tam bir kayıptayım.

Elimden gelenin ne olduğunu ve nasıl olabileceğimi düşündüğümüzü göstermek için elimden gelenin en iyisi, ama ne yazık ki eksik ve üzgünüm.

With CTE_FirstSaleDate as 
(
SELECT MIN(TransDate) as FirstSoldOn FROM InventoryTransaction 
), 
WITH CTE_AllDatesTable 
AS 
(
    SELECT FirstSoldOn AS [date] 
    UNION ALL 
    SELECT DATEADD(dd, 1, [date]) 
    FROM CTE_DatesTable 
    WHERE DATEADD(dd, 1, [date]) < DATEADD(dd, 30, FirstSoldOn) 
), 
CTE_OOS as 
(
SELECT TOP 1 i.ItemCode, it.TransactionDate 
FROM InventoryTransaction it 
WHERE (it.OnHandAfter = 0) 
ORDER BY it.TransactionDate DESC 
) 
Select i.ItemCode, DaysCount, DaysOOSCount, AvgDlyVol, AdjDlyVol 
From Items i 
Join InventoryTransaction... 

Ben tablolarda tablolarda değildir ve tüm bu diğer şeyler birlikte büyük takdir edilecektir, dinamik tarihleri ​​bir demet nasıl alabilirim ilişkin Herhangi bir yardım. Bir büyülü betik varsa harika olurdu, ancak bu ay başına bir kez çalıştırılacak, böylece onu kırmak gayet iyi.

+0

o bir şeyin stokta kalmadığı gerçek tarihleri ​​veya sadece gün sayısını öğrenmek mi? –

+0

Sadece sayı günleri. Kısmen ayarlanmış günlük hacmi hesaplamak için ama aynı zamanda bir şey stokta kalmadığı zamanın yüzdesini görmek için. Örnek veriler gibi kazmak kadar kötü görünmüyor ve neredeyse zamanın% 50'sinin stokta olduğunu fark etmiyor. – user3096720

+0

ItemCode her işlem için benzersiz bir tanımlayıcıdır ve sırayla ayrılmıştır? – Turophile

cevap

0

stokta gün sayısını almak için bu deneyin:

;WITH CTE 
AS 
(
    SELECT *, ROW_NUMBER() OVER (ORDER BY TransaDate) as RN 
    FROM InventoryTransaction 
) 
SELECT c1.TransaDate, c2.TransaDate, DATEDIFF(d, c1.TransaDate, c2.TransaDate) As NumDays 
FROM CTE C1 
INNER JOIN CTE C2 
    ON C1.RN = C2.RN - 1 
WHERE C1.OnHandAfter = 0 AND C2.OnHAndBefore = 0 

DÜZENLEME

Ben ItemCode belirli Öğe için tüm işlemleri bağlayan şey sütunu (olduğunu varsayarsak Bu sizin örnekleminizden tam olarak görünmüyorsa, o zaman bu sorgu çalışırdı:

;WITH CTE 
AS 
(
    SELECT * 
      ,ROW_NUMBER() OVER (Partition By ItemCode ORDER BY TransaDate) as RN 
    FROM InventoryTransaction 
) 
SELECT c1.TransaDate, c2.TransaDate, 
     DATEDIFF(d, c1.TransaDate, COALESCE(c2.TransaDate, c1.TransaDate)) As NumDays 
FROM CTE C1 
LEFT JOIN CTE C2 
    ON C1.RN = C2.RN - 1 AND C1.ItemCode = C2.ItemCode 
WHERE C1.OnHandAfter = 0 AND C2.OnHAndBefore = 0 
+0

Bu çalışıyor. Birkaç tarih aralığını ve farklı öğeleri test ettim ve karşılaştığım tek sorun, öğenin tarih aralığının sonunda stokta kalmasıdır. Örneğin, tarih aralığı 03/01 - 03/31 ise ve öğe 03/30 tarihinde stoktan çıkarsa, sonuç c1.TransDate = 2016-03-30, c2.TransDate = 2013-07-17 ve NumDays = -987. Bir sonraki satırın 2013-07-17 nasıl bulunduğundan emin değilim. NumDays <0 sonra EndDate - C2.TransDate ise, belki basit bir IF yapabilirim. – user3096720

+0

@ user3096720 Bu soruna yardımcı olması için sorunuza daha fazla veri ekleyebilirsiniz. 1 öğeden fazlaysa, katılımcınız bunu da içermelidir. Örnek verilerinizden öğe kodunuz bir öğeyi tanımlamak için görünmüyorsa ne kullanması gerektiğini göremedim. –

+0

Kurallar sağladığınız ikinci versiyon! Bunu gerçekten çalışmak zorunda kalacağım, Kendimi birleştiren bölünmüş CTE benim için görselleştirmek veya anlamak için kolay değil ama onlarla daha fazla çalışmaya ihtiyacım var. Sağladığınız ilk sürüm çalıştı ama çalıştırmak için yaklaşık 2 dakika sürdü. İkinci versiyon bir saniyenin altında koştu. Şaşırtıcı! Bölünme olduğunu farz edelim ki, sol birleşim içsel birleşmeden daha hızlı değilse, şeyi hızlandırır. Teşekkürler Steve, benimle oynamak için bu yeni, parlak eğitici oyuncak için teşekkür ederim. Şu anda içtenlikle sersemiyim! – user3096720