none
Günlük İşlemleri Ay Bazında Gruplama RRS feed

  • Soru

  • Merhabalar,

    Günlük işlemlerin olduğu bir tablom var, buradan bazı kırılım ve gruplamalarla ay bazında toplamları almak istiyorum. Nasıl yapıldığını bilemediğimden tarih aralığını her seferinde değiştiriyorum. 12 defa bunu çalıştırıyorum.

    PURCHASE_DATE BETWEEN '2018-03-01' AND '2018-04-01'

    PURCHASE_DATE BETWEEN '2018-04-01' AND '2018-05-01'

    PURCHASE_DATE BETWEEN '2018-05-01' AND '2018-05-01'

    Tek bir sorguda tarih aralığını PURCHASE_DATE BETWEEN '2018-01-01' AND '2018-12-31' vererek ay bazında nasıl gruplayabilirim? Her kaydın yanına Ait olduğu ay yazabilirse çok iyi olur.

    Tam sorgum aşağıdaki gibidir.


    select  b.PRODUCT_NUMBER as 'Debit Ürün Kodu', 
    c.PRODUCT_NUMBER as 'Prepaid Ürün Kodu', 
    d.PRODUCT_NAME as 'Ürün Adı', 
    COUNT(*) AS 'İşlem Adeti', 
    (case a.CLEARING_TRN_CODE when '07' then 'Nakit Çekim' when '05' then 'Harcama' end) as 'İşlem Tipi', 
    sum(a.DESTINATION_AMOUNT) as 'Toplam Tutar'
    (case A.DESTINATION_CURRENCY_CODE when '840' then 'USD' when '949' then 'TRL' end) as 'Kur'

    from PRP.TRN_CLEARING_POOL A

    left join dbt.DEBIT_CARD_MASTER b on a.SHADOW_CARD_NUMBER=b.SHADOW_CARD_NUMBER
    left join prp.PREPAID_CARD_MASTER c on a.SHADOW_CARD_NUMBER=c.SHADOW_CARD_NUMBER
    left join prm.CARD_PRODUCT d on b.PRODUCT_NUMBER=d.PRODUCT_NUMBER or c.PRODUCT_NUMBER=d.PRODUCT_NUMBER

    WHERE PURCHASE_DATE BETWEEN '2018-03-01' AND '2018-04-01' AND A.CLEARING_TRN_CODE in('05','07')
    GROUP BY  a.CLEARING_TRN_CODE,A.DESTINATION_CURRENCY_CODE,b.PRODUCT_NUMBER,c.PRODUCT_NUMBER,d.PRODUCT_NAME
    order by b.PRODUCT_NUMBER,c.PRODUCT_NUMBER

    23 Ocak 2019 Çarşamba 11:12

Yanıtlar

  • GROUP BY  MONTH(PURCHASE_DATE)


    Altan Özdemir

    • Yanıt Olarak İşaretleyen ErsinBicer 23 Ocak 2019 Çarşamba 14:10
    23 Ocak 2019 Çarşamba 11:25
  • with pool (SHADOW_CARD_NUMBER, purYear, purMonth, CLEARING_TRN_CODE, DESTINATION_CURRENCY_CODE, toplam, sayi) as 
    (
     select SHADOW_CARD_NUMBER, 
      year(PURCHASE_DATE),
      month(PURCHASE_DATE),
      CLEARING_TRN_CODE, DESTINATION_CURRENCY_CODE, 
      sum(DESTINATION_AMOUNT), COUNT(*)
     from PRP.TRN_CLEARING_POOL
     where PURCHASE_DATE >= '20180301' AND PURCHASE_DATE < '20180401' AND CLEARING_TRN_CODE in ('05','07')
     group by SHADOW_CARD_NUMBER, year(PURCHASE_DATE),month(PURCHASE_DATE),CLEARING_TRN_CODE, DESTINATION_CURRENCY_CODE
    )
    select  b.PRODUCT_NUMBER as 'Debit Ürün Kodu', 
            c.PRODUCT_NUMBER as 'Prepaid Ürün Kodu', 
            d.PRODUCT_NAME as 'Ürün Adı',
    		a.purYear as Yil, a.PurMonth as Ay,
            a.Sayi AS 'İşlem Adeti', 
            case a.CLEARING_TRN_CODE when '07' then 'Nakit Çekim' when '05' then 'Harcama' end as 'İşlem Tipi', 
            a.toplam as 'Toplam Tutar'
            case A.DESTINATION_CURRENCY_CODE when '840' then 'USD' when '949' then 'TRL' end as 'Kur'
    from pool A
    left join dbt.DEBIT_CARD_MASTER b on a.SHADOW_CARD_NUMBER=b.SHADOW_CARD_NUMBER
    left join prp.PREPAID_CARD_MASTER c on a.SHADOW_CARD_NUMBER=c.SHADOW_CARD_NUMBER
    left join prm.CARD_PRODUCT d on b.PRODUCT_NUMBER=d.PRODUCT_NUMBER or c.PRODUCT_NUMBER=d.PRODUCT_NUMBER
    order by b.PRODUCT_NUMBER,c.PRODUCT_NUMBER;

    Dikkat edilmesi gereken noktalar:

    Aggregasyon islemlerini, özellikle de SUM() islemini JOIN olan yerlerde yaparken çok dikkatli olmak gerekli, tercihan hatayı önlemek icin, JOIN oncesi bagimsiz olarak bu isi yapmak daha iyi.

    Tarih araliginda BETWEEN, MS SQL Server ile hataya açık. BETWEEN >= ve <= anlamondadir, yani alt ve üst degerler "dahil" olarak islem gorur. Oysa tarih kismi, saat bilgisini de içeriyorsa, >= ve < seklinde araligin alınması gerekir (DateTime tipi 3ms hassasiyete sahiptir). Onun icin yukarıdaki ornekteki gibi MART 2018 kayıtları icin:

    purchase_Date >= '20180301' and purchase_date < '20180401'

    kullanilmistir. Yine tarih literallerinin yazılmasında yyyyMMdd seklinde yazilmasina ozen gostermeli, arada /, - veya . gibi ayraçları kullanmamalıyız. MS SQL serverin bazı versiyonlarında, bu ayraçların kullanılması, kullanılan dile bağlı olarak hata yaratabilmektedir. 

    • Yanıt Olarak Öneren Altan Özdemir 23 Ocak 2019 Çarşamba 13:18
    • Yanıt Olarak İşaretleyen ErsinBicer 23 Ocak 2019 Çarşamba 14:10
    23 Ocak 2019 Çarşamba 12:33

Tüm Yanıtlar

  • GROUP BY  MONTH(PURCHASE_DATE)


    Altan Özdemir

    • Yanıt Olarak İşaretleyen ErsinBicer 23 Ocak 2019 Çarşamba 14:10
    23 Ocak 2019 Çarşamba 11:25
  • with pool (SHADOW_CARD_NUMBER, purYear, purMonth, CLEARING_TRN_CODE, DESTINATION_CURRENCY_CODE, toplam, sayi) as 
    (
     select SHADOW_CARD_NUMBER, 
      year(PURCHASE_DATE),
      month(PURCHASE_DATE),
      CLEARING_TRN_CODE, DESTINATION_CURRENCY_CODE, 
      sum(DESTINATION_AMOUNT), COUNT(*)
     from PRP.TRN_CLEARING_POOL
     where PURCHASE_DATE >= '20180301' AND PURCHASE_DATE < '20180401' AND CLEARING_TRN_CODE in ('05','07')
     group by SHADOW_CARD_NUMBER, year(PURCHASE_DATE),month(PURCHASE_DATE),CLEARING_TRN_CODE, DESTINATION_CURRENCY_CODE
    )
    select  b.PRODUCT_NUMBER as 'Debit Ürün Kodu', 
            c.PRODUCT_NUMBER as 'Prepaid Ürün Kodu', 
            d.PRODUCT_NAME as 'Ürün Adı',
    		a.purYear as Yil, a.PurMonth as Ay,
            a.Sayi AS 'İşlem Adeti', 
            case a.CLEARING_TRN_CODE when '07' then 'Nakit Çekim' when '05' then 'Harcama' end as 'İşlem Tipi', 
            a.toplam as 'Toplam Tutar'
            case A.DESTINATION_CURRENCY_CODE when '840' then 'USD' when '949' then 'TRL' end as 'Kur'
    from pool A
    left join dbt.DEBIT_CARD_MASTER b on a.SHADOW_CARD_NUMBER=b.SHADOW_CARD_NUMBER
    left join prp.PREPAID_CARD_MASTER c on a.SHADOW_CARD_NUMBER=c.SHADOW_CARD_NUMBER
    left join prm.CARD_PRODUCT d on b.PRODUCT_NUMBER=d.PRODUCT_NUMBER or c.PRODUCT_NUMBER=d.PRODUCT_NUMBER
    order by b.PRODUCT_NUMBER,c.PRODUCT_NUMBER;

    Dikkat edilmesi gereken noktalar:

    Aggregasyon islemlerini, özellikle de SUM() islemini JOIN olan yerlerde yaparken çok dikkatli olmak gerekli, tercihan hatayı önlemek icin, JOIN oncesi bagimsiz olarak bu isi yapmak daha iyi.

    Tarih araliginda BETWEEN, MS SQL Server ile hataya açık. BETWEEN >= ve <= anlamondadir, yani alt ve üst degerler "dahil" olarak islem gorur. Oysa tarih kismi, saat bilgisini de içeriyorsa, >= ve < seklinde araligin alınması gerekir (DateTime tipi 3ms hassasiyete sahiptir). Onun icin yukarıdaki ornekteki gibi MART 2018 kayıtları icin:

    purchase_Date >= '20180301' and purchase_date < '20180401'

    kullanilmistir. Yine tarih literallerinin yazılmasında yyyyMMdd seklinde yazilmasina ozen gostermeli, arada /, - veya . gibi ayraçları kullanmamalıyız. MS SQL serverin bazı versiyonlarında, bu ayraçların kullanılması, kullanılan dile bağlı olarak hata yaratabilmektedir. 

    • Yanıt Olarak Öneren Altan Özdemir 23 Ocak 2019 Çarşamba 13:18
    • Yanıt Olarak İşaretleyen ErsinBicer 23 Ocak 2019 Çarşamba 14:10
    23 Ocak 2019 Çarşamba 12:33
  • Teşekkür ederim
    23 Ocak 2019 Çarşamba 13:57