Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Niestandardowa kalkulacja kwoty

Oto alternatywne podejście, które wymaga funkcji LAG() dostępnej w SQL 2012, ale zauważ, że przykładowe dane nie zawierają „28 różnych dni” przed każdą datą. Również rzeczywisty używany typ danych nie jest znany (data/smalldatetime/datetime/datetime2) ani nie wiadomo, czy potrzebne jest skrócenie czasu od daty. Tak więc z pewnymi zastrzeżeniami to podejście tworzy serię zakresów dat dla 28 różnych dat (ale jeśli dane ich nie dostarczają, oznacza to, że upłynęło 28 dni). Oto demo programu sqlfiddle

Konfiguracja schematu PostgreSQL 9.3 :(ponieważ SQL Server nie działa w 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)
;

Zapytanie 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

Wyniki :

| 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 |

Uwaga:dla serwera SQL

  • zamiast theDay - INTERVAL '28 DAYS' użyj dateadd(dzień,-28,dzień)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Znajdź dane dla każdego kolejnego roku finansowego w zapytaniu mdx

  2. Lista kopii zapasowych planu konserwacji SQL Server 2008

  3. SQL:znaleźć ciągłe zakresy dat w wielu wierszach?

  4. Nie można użyć w operatorze PRZESTAWNYM, ponieważ nie jest niezmienny w stosunku do wartości NULL

  5. Naruszenie błędu ograniczenia PRIMARY KEY SQL