2009-03-04 7 views
3

Belirli tarihleri ​​ifade eden zamanlama bilgilerini içeren bir tablonuz varsa, bu bilgiyi bir tür CROSS JOIN kullanarak, belki de bu bilgileri gerçek satırlara dönüştürmek için yazılabilen bir SQL ifadesi var mıdır? ayları uzunluğu - tarifesi başlıyor tarihi (1 ödeme bu tarihte kaynaklanmaktadır) Güncel tarih tarifeleri temelinde gerçek tarihler çizmek için SQL kullanabilir miyim?

  • Terim -

    • BaşlangıçTarihi:

      bu sütunlu bir ödeme planı tablo düşünün zamanlama
    • Frekans - rekürenslerin arasındaki ayların sayısı
    • PaymentAmt -
     
    SchedID StartDate Term Frequency PaymentAmt 
    ------------------------------------------------- 
    1  05-Jan-2003 48 12   1000.00 
    2  20-Dec-2008 42 6   25.00 
    

    beni aşağıdakilere yukarıdan devam etmesine izin için tek bir SQL deyimi var mı

  • :-) ödeme miktarı?

     
               Running 
    SchedID Payment Due   Expected 
         Num  Date   Total 
    -------------------------------------- 
    1  1  05-Jan-2003 1000.00 
    1  2  05-Jan-2004 2000.00 
    1  3  05-Jan-2005 3000.00 
    1  4  05-Jan-2006 4000.00 
    1  5  05-Jan-2007 5000.00 
    2  1  20-Dec-2008 25.00 
    2  2  20-Jun-2009 50.00 
    2  3  20-Dec-2009 75.00 
    2  4  20-Jun-2010 100.00 
    2  5  20-Dec-2010 125.00 
    2  6  20-Jun-2011 150.00 
    2  7  20-Dec-2011 175.00 
    

    Ben MS SQL Server 2005 (yakında yükseltme için hiçbir umut) kullanıyorum ve zaten bir tablo değişkeni ve while döngüsü kullanarak yapabilirsiniz, ancak CROSS'un çeşit geçerli olacak JOIN gibi görünüyordu ama Bunun nasıl işe yaradığını bilmiyorum.

    Düşünceleriniz takdir edilmektedir.

    DÜZENLEME: Aslında başlangıçta 2000 dediğim halde SQL Server kullanıyorum. Düşündüğüm kadar geriye doğru değiliz. Afedersiniz.

    cevap

    2

    Şu anda kodu test, bu yüzden bir fiske tuz ile götürün ama bir şey soruya cevap gerektiğini az çok takip benzeyen olduğunu düşünemiyorum: Evet

    with q(SchedId, PaymentNum, DueDate, RunningExpectedTotal) as 
        (select SchedId, 
          1 as PaymentNum, 
          StartDate as DueDate, 
          PaymentAmt as RunningExpectedTotal 
        from PaymentScheduleTable 
        union all 
        select q.SchedId, 
          1 + q.PaymentNum as PaymentNum, 
          DATEADD(month, s.Frequency, q.DueDate) as DueDate, 
          q.RunningExpectedTotal + s.PaymentAmt as RunningExpectedTotal 
        from q 
          inner join PaymentScheduleTable s 
            on s.SchedId = q.SchedId 
        where q.PaymentNum <= s.Term/s.Frequency) 
    select * 
    from q 
    order by SchedId, PaymentNum 
    
    +0

    WOW !! Bu sıcak! Sadece sorgunuzu denedim ve gerçekten işe yarıyor. Bir sonraki saatini (sadece bir saat, umarım) oraya nasıl gideceğini anlamaya çalışacağım. Çok teşekkürler. Şimdi kesinlikle daha akıllıyım (ya da bir saat içinde olacağım). :-) – witttness

    1

    Benzer bir sonuç elde etmek için tablo değerli işlevler kullandım. Temelde bildiğim bir tablo değişkenini kullanmakla aynı, ama tasarımdan gerçekten memnun olduğumu hatırlıyorum.

    kullanım bence, çok iyi okuyarak biter:

    /* assumes @startdate and @enddate schedule limits */ 
    
    SELECT 
        p.paymentid, 
        ps.paymentnum, 
        ps.duedate, 
        ps.ret 
    FROM 
        payment p, 
        dbo.FUNC_get_payment_schedule(p.paymentid, @startdate, @enddate) ps 
    ORDER BY p.paymentid, ps.paymentnum 
    
    +0

    Bunu böyle yapıyordum, ama bu süreçte OUGHT'un daha iyi (daha temiz) bir yol olduğu görünüyordu. – witttness

    +0

    Dürüst olmak gerekirse, bir süredir SQL kullanmıyorum ve belki de bu tasarımdan hoşlanıyorum çünkü bana alıştığım programlama tarzını hatırlatıyor. Bunu neden temiz SQL'de yapmak istediğinizi anlıyorum ve soruyu beğeniyorum. – overslacked

    0

    Tipik çözüm Takvim tablosunu kullanmaktır. Kendi ihtiyaçlarına uygun genişletmek, ancak benzer görünümde olacaktır: sizin için alakalı diğer sütunlar ekleyebilirsiniz is_holiday ek olarak

    CREATE TABLE Calendar 
    (
        calendar_date DATETIME NOT NULL, 
        is_holiday BIT NOT NULL DEFAULT(0), 
        CONSTRAINT PK_Calendar PRIMARY KEY CLUSTERED calendar_date 
    ) 
    

    . Tabloyu sonraki 10 veya 100 veya 1000 yıl içinde doldurmak için bir komut dosyası yazabilirsiniz ve her şey ayarlanmalıdır. Daha basit yapmaya çalıştığınız ve size ek işlevsellik kazandırabilecekleri sorgulamalar yapar.

    +0

    Ne yazık ki, zaman çizelgesi tablosu, devralınan tasarımın bir parçasıdır. Bahsettiğin gibi bir Takvim tablosu için onu bırakamam. Farklı bir senaryoda olabilirim. Yine de teşekkürler. – witttness

    +0

    Şu anki tasarımınızı terk etmenizi önermiyorum. Takvim tablosunu, mevcut tablonuz ile tarihlere göre birleştirerek kullanabilirsiniz. Tipik olarak böyle kullanılırlar. –

    1

    Tam sayılardan oluşan bir tablo (veya daha iyisi: http://www.sql-server-helper.com/functions/integer-table.aspx) ve biraz tarih matematiği, e..g. başlangıç ​​+ int * frekansı

    +0

    Ben bu fikri beğenirim, ancak bu tam olarak bir cevap değildir. Muhtemelen bir tarih ve sıklığı alan ve bunu bir CROSS UYGULAMASI ile birlikte kullanan ve herhangi bir program için yeniden kullanabileceğim bir işlev yaratacağım. – witttness