web-dev-qa-db-ja.com

時間の経過に伴う合計トランザクションのローリングカウント

1週間の間隔で一連の合計トランザクションを取得する必要があります。本質的に私はこれまでの合計トランザクション列が必要です。 WEEK(Date)でグループ化すると、その週のトランザクションの量を取得しますが、その週の前の任意の時間からのトランザクションも取得する必要があります。

だから私はこのようなテーブルがあるとしましょう:

TransactionID  | Date
---------------|-----------
             1 | 8-04-2014
             2 | 8-05-2014
             3 | 8-18-2014
             4 | 8-18-2014
             5 | 8-20-2014

次のようなものを提供するselectステートメントが欲しい

TotalTransactionsToDate | Week | Year
------------------------|------|------
                      2 |    1 | 2014
                      5 |    3 | 2014

MySql 5.5.38を使用しています

2
damian

必要なのは累積合計と呼ばれ、次のようなことができます。

create table transactions (transactionid int, d date);
insert into transactions (transactionid, d) 
    values (1, '2014-08-04'),(2,'2014-08-05'), (3, '2014-08-18')
         , (4, '2014-08-18'), (5,'2014-08-20');

select x.y, x.w,  count(1) 
from ( 
   select distinct year(d) as y, week(d) as w 
   from transactions
) as x 
join transactions y 
    on year(y.d) < x.y
    or ( year(y.d) = x.y
     and week(y.d) <= x.w ) 
group by x.y, x.w;  

+------+------+----------+
| y    | w    | count(1) |
+------+------+----------+
| 2014 |   31 |        2 |
| 2014 |   33 |        5 |
+------+------+----------+

2014年の2 2に対する追加のリクエストはありませんでした。次のように置き換えることでそれを行うことができます。

select distinct year(d) as y, week(d) as w 
from transactions 

...ドメイン全体を数週間作成する式を使用します。多くの場合、欠損値などのレポートを取得するために結合に使用できるカレンダーテーブルを作成することをお勧めします。

2
Lennart

基本データを取得するには、集計が必要です。

select 1 + floor(datediff(date, mind) / 7) as week,
       year(date) as year,
       count(*) as num
from atable t cross join
     (select min(date) as mind
      from atable
     ) td
group by 1 + floor(datediff(date, mind) / 7),
         year(date)

変数を使用してこれを拡張し、累積合計を取得できます。

select week, year, num, (@cum := @cum + num) as cum
from (select 1 + floor(datediff(date, mind) / 7) as week,
             year(date) as year,
             count(*) as num
      from atable t cross join
           (select min(date) as mind
            from atable
           ) td
      group by 1 + floor(datediff(date, mind) / 7),
               year(date)
     ) x cross join
     (select @cum := 0) vars
order by year, week;
2
Gordon Linoff

たぶん、あなたはそれを日付の最新の月曜日でグループ化することができます

SELECT COUNT(1) Transactions,WEEK(monday) Week,YEAR(monday) Year
(
    SELECT (Date - INTERVAL WEEKDAY(Date) DAY) monday
    FROM mytable WHERE Date >= MAKEDATE(YEAR(NOW()),1)
) A GROUP BY YEAR(monday),WEEK(monday);

[〜#〜] note [〜#〜]:サブクエリのWHERE句は、年の初めからすべてを収集します。適切なWHERE句を使用できます。

私が正しく理解している場合は、スプレッドシートのように、日付の前のすべての週の合計を毎週ロールアップする必要があります。ユーザー定義変数を設定し、反復と合計を実行する必要があります

SET @S = 0;
SELECT
    (@S:=@S+Transactions) TotalTransactionsToDate,
    Week,Year
FROM
(
    SELECT COUNT(1) Transactions,WEEK(monday) Week,YEAR(monday) Year
    (
        SELECT (Date - INTERVAL WEEKDAY(Date) DAY) monday
        FROM mytable WHERE Date >= MAKEDATE(YEAR(NOW()),1)
    ) A GROUP BY YEAR(monday),WEEK(monday)
) AA;

試してみる !!!

1
RolandoMySQLDBA