3

広告キャンペーンの予算履歴を保存するための表を次に示します。

キャンペーン_予算_履歴

id_campaign  budget date
1            10     2013-01-01
1            15     2013-01-03
1            10     2013-01-05

ある日付のデータがない場合は、最後に設定された予算と同じになります。

予算の合計を日付範囲(たとえば、「2013-01-02」から「2013-01-06」まで)でカウントするにはどうすればよいですか。'2013-01-02'の予算は'2013-01-01'に等しく、'2013-01-04'の予算は'2013-01-03に等しいため、結果は$60である必要があります。 '。

SQLを介してそれを行う方法はありますか?

4

2 に答える 2

1

この例では、カレンダー(ユーティリティ)テーブルを使用しています...

SELECT * FROM calendar WHERE dt BETWEEN '2012-12-27' AND '2013-01-12';
+------------+
| dt         |
+------------+
| 2012-12-27 |
| 2012-12-28 |
| 2012-12-29 |
| 2012-12-30 |
| 2012-12-31 |
| 2013-01-01 |
| 2013-01-02 |
| 2013-01-03 |
| 2013-01-04 |
| 2013-01-05 |
| 2013-01-06 |
| 2013-01-07 |
| 2013-01-08 |
| 2013-01-09 |
| 2013-01-10 |
| 2013-01-11 |
| 2013-01-12 |
+------------+

SELECT SUM(budget) total
  FROM campaign_budgets_history a
  JOIN 
     ( SELECT MAX(y.date) max_date 
         FROM calendar x 
         JOIN campaign_budgets_history y 
           ON y.date <= x.dt 
        WHERE x.dt BETWEEN '2013-01-02' AND '2013-01-06'
        GROUP
           BY x.dt           
     ) b
    ON b.max_date = a.date;
于 2013-01-11T11:20:19.490 に答える
1

ここにあなたへの質問があります。ユーザー変数を使用してクエリ範囲の終わりを示しますが、最終バージョンでは代わりにパラメーター プレースホルダーを使用する可能性があります。は、クエリした範囲の@endの最初の日です。つまり、範囲の排他的な終了日です。

SET @begin = '2013-01-02';
SET @end = '2013-01-07';

SELECT
  SUM(DATEDIFF(IF(CAST(c.end AS date) > CAST(@end AS date),
                  CAST(@end AS date),
                  CAST(c.end AS date)
                 ),
               IF(c.begin < CAST(@begin AS date),
                  CAST(@begin AS date),
                  c.begin
                 )
              ) * c.budget
     ) AS overall_budget
FROM
(SELECT a.id_campaign,
        a.date begin,
        MIN(IFNULL(b.date, CAST(@end AS date))) end,
        a.budget
 FROM campaign_budgets_history a
 LEFT JOIN campaign_budgets_history b
        ON a.id_campaign = b.id_campaign AND a.date < b.date
 WHERE a.date < CAST(@end AS date)
 GROUP BY a.id_campaign, a.date
 HAVING end > CAST(@begin AS date)
) c;

SQL Fiddleでテスト済み。すべてのキャストが必要と思われる理由は不明ですが、一部を回避する方法がある可能性があります。しかし、上記は機能しているように見えますが、キャストが少ない一部のバージョンでは機能しませんでした。

アイデアは、サブクエリが範囲のテーブルを作成し、それぞれが特定の予算が有効であった日付を示すというものです。クエリ範囲の先頭と一致するように、最初の範囲の先頭を調整する必要がある場合があります。次に、日付を差し引いてそれぞれの日数を取得し、その数に 1 日の予算を掛けます。

于 2013-01-11T10:11:07.897 に答える