Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Calcul personnalisé du montant

Voici une approche alternative qui nécessite LAG() qui est disponible à partir de SQL 2012, mais notez que les exemples de données ne contiennent pas "28 jours distincts" avant chaque date. De plus, le type de données réel utilisé n'est pas connu (date/smalldatetime/datetime/datetime2) et on ne sait pas non plus si la troncation de l'heure à partir de la date est nécessaire. Donc, avec quelques mises en garde, cette approche crée une série de plages de dates pour les 28 dates distinctes (mais si les données ne les fournissent pas, alors ce sont 28 jours écoulés). Voici une démo sqlfiddle

Configuration du schéma PostgreSQL 9.3 :(car SQL Server ne fonctionne pas sur sqlfiddle)

CREATE TABLE Table1
    (theDate timestamp, Value int, promo int, item int)
;

INSERT INTO Table1
    (theDate, Value, promo, item)
VALUES
    ('2011-01-01 00:00:00', 626, 0, 1230),
    ('2011-01-02 00:00:00', 231, 1, 1230),
    ('2011-01-03 00:00:00', 572, 1, 1230),
    ('2011-01-04 00:00:00', 775, 1, 1230),
    ('2011-01-05 00:00:00', 660, 1, 1230),
    ('2011-01-06 00:00:00', 662, 1, 1230),
    ('2011-01-07 00:00:00', 541, 1, 1230),
    ('2011-01-08 00:00:00', 849, 1, 1230),
    ('2011-01-09 00:00:00', 632, 1, 1230),
    ('2011-01-10 00:00:00', 906, 1, 1230),
    ('2011-01-11 00:00:00', 961, 1, 1230),
    ('2011-01-12 00:00:00', 361, 0, 1230),
    ('2012-01-01 00:00:00', 461, 0, 1230),
    ('2012-01-02 00:00:00', 928, 1, 1230),
    ('2012-01-03 00:00:00', 855, 0, 1230),
    ('2012-01-04 00:00:00', 605, 0, 1230),
    ('2012-01-05 00:00:00', 83, 0, 1230),
    ('2012-01-06 00:00:00', 44, 0, 1230),
    ('2012-01-07 00:00:00', 382, 0, 1230),
    ('2012-01-08 00:00:00', 862, 0, 1230),
    ('2012-01-09 00:00:00', 549, 0, 1230),
    ('2012-01-10 00:00:00', 632, 0, 1230),
    ('2012-01-11 00:00:00', 2, 0, 1230),
    ('2012-01-12 00:00:00', 26, 0, 1230)
;

Requête 1 :

select
      t1.item
    , ranges.theStart
    , ranges.theEnd
    , sum(t1.value)
    , sum(t1.value) / 28 avg
from (
      select
            coalesce(lag(theDay,28) over(order by theDay) , theDay - INTERVAL '28 DAYS') as theStart
          , theDay as theEnd
      from (
            select distinct cast(thedate as date) theDay from Table1
            ) days
      ) ranges
inner join table1 t1 on theDate between ranges.theStart and ranges.theEnd
group by
      t1.item
    , ranges.theStart
    , ranges.theEnd

Résultats :

| item |                   thestart |                    theend |  sum | avg |
|------|----------------------------|---------------------------|------|-----|
| 1230 | December, 04 2010 00:00:00 | January, 01 2011 00:00:00 |  626 |  22 |
| 1230 | December, 05 2010 00:00:00 | January, 02 2011 00:00:00 |  857 |  30 |
| 1230 | December, 06 2010 00:00:00 | January, 03 2011 00:00:00 | 1429 |  51 |
| 1230 | December, 07 2010 00:00:00 | January, 04 2011 00:00:00 | 2204 |  78 |
| 1230 | December, 08 2010 00:00:00 | January, 05 2011 00:00:00 | 2864 | 102 |
| 1230 | December, 09 2010 00:00:00 | January, 06 2011 00:00:00 | 3526 | 125 |
| 1230 | December, 10 2010 00:00:00 | January, 07 2011 00:00:00 | 4067 | 145 |
| 1230 | December, 11 2010 00:00:00 | January, 08 2011 00:00:00 | 4916 | 175 |
| 1230 | December, 12 2010 00:00:00 | January, 09 2011 00:00:00 | 5548 | 198 |
| 1230 | December, 13 2010 00:00:00 | January, 10 2011 00:00:00 | 6454 | 230 |
| 1230 | December, 14 2010 00:00:00 | January, 11 2011 00:00:00 | 7415 | 264 |
| 1230 | December, 15 2010 00:00:00 | January, 12 2011 00:00:00 | 7776 | 277 |
| 1230 | December, 04 2011 00:00:00 | January, 01 2012 00:00:00 |  461 |  16 |
| 1230 | December, 05 2011 00:00:00 | January, 02 2012 00:00:00 | 1389 |  49 |
| 1230 | December, 06 2011 00:00:00 | January, 03 2012 00:00:00 | 2244 |  80 |
| 1230 | December, 07 2011 00:00:00 | January, 04 2012 00:00:00 | 2849 | 101 |
| 1230 | December, 08 2011 00:00:00 | January, 05 2012 00:00:00 | 2932 | 104 |
| 1230 | December, 09 2011 00:00:00 | January, 06 2012 00:00:00 | 2976 | 106 |
| 1230 | December, 10 2011 00:00:00 | January, 07 2012 00:00:00 | 3358 | 119 |
| 1230 | December, 11 2011 00:00:00 | January, 08 2012 00:00:00 | 4220 | 150 |
| 1230 | December, 12 2011 00:00:00 | January, 09 2012 00:00:00 | 4769 | 170 |
| 1230 | December, 13 2011 00:00:00 | January, 10 2012 00:00:00 | 5401 | 192 |
| 1230 | December, 14 2011 00:00:00 | January, 11 2012 00:00:00 | 5403 | 192 |
| 1230 | December, 15 2011 00:00:00 | January, 12 2012 00:00:00 | 5429 | 193 |

NB :Pour SQL Server

  • au lieu de theDay - INTERVAL '28 DAYS' utilisez dateadd(day,-28,theDay)