2012-02-21 41 views
0

我有一個表的命令是這樣的:像這樣累積計數隨着時間的推移

customer_id order_date 

10   2012-01-01 
11   2012-01-02 
10   2012-01-02 
12   2012-01-03 
11   2012-01-04 

12   2012-02-01 
11   2012-02-04 
13   2012-02-05 
14   2012-02-06 

我怎樣才能得到一個累計平均隨着時間的推移(每月):

order date count orders count customers (customer_id) 
2012-01  1    1     (12) 
2012-01  2    2     (10,11) 
2012-02  1    2     (13,14) 
2012-02  2    2     (10,12 
2012-02  3    2     (11) 

展示瞭如何的數客戶與每個客戶的訂單數量隨時間發展。

下面的查詢給我想要的信息 - 但不是隨着時間的推移。我如何隨時間迭代查詢?

SELECT number_of_orders, count(*) as amount FROM (
SELECT o.customer_id, count(*) as number_of_orders 
    FROM orders o 
GROUP BY o.customer_id) as t1 
GROUP BY number_of_orders 

更新:

現在已經建立了下面的PHP代碼生成我需要什麼,不知道這是否可以使用累積計數像http://www.freeopenbook.com/mysqlcookbook/mysqlckbk-chp-12-sect-14.html

$year = 2011; 
    for ($cnt_months = 1; $cnt_months <= 12; $cnt_months++) { 
     $cnt_months_str = ($cnt_months < 10) ? '0'.$cnt_months : $cnt_months; 
     $raw_query = "SELECT number_of_orders, count(*) as amount 
       FROM (
       SELECT 
       o.customer_id, 
       count(*) as number_of_orders 
       FROM orders o 
       where Date_Format(o.order_date, '%Y%m') >= " . $year . "01 and Date_Format(o.order_date, '%Y%m') <= " . $year . $cnt_months_str . " 
       GROUP BY o.customer_id) as t1 
       GROUP BY number_of_orders"; 

     $query = db_query($raw_query); 
     while ($row = db_fetch_array($query)) { 
      $data[$cnt_months_str][$row['number_of_orders']] = array($row['number_of_orders'], (int)$row['amount']); 

     } 
    } 

回答

2

好做起點爲

SELECT 
    order_date, 
    COUNT(*) AS distinctOrders, 
    COUNT(DISTINCT customer_id) AS distinctCustomers, 
    GROUP_CONCAT(DISTINCT customer_id ASC) AS customerIDs 
FROM orders 

GROUP BY order_date ASC 

這會爲您提供order_date,該日期的訂單數量,該日期的客戶數量以及該日期的客戶ID列表。

只是尋找一種逐月計算方法。因此,採取這種正向我用一個子查詢相符了,因爲它去

SELECT 
    ordersPerDate.*, 
    IF(
     MONTH(ordersPerDate.order_date)[email protected], 
     @runningTotal := @runningTotal+ordersPerDate.distinctOrders, 
     @runningTotal := 0 
    ) AS ordersInThisMonth, 
    @thisMonth := MONTH(ordersPerDate.order_date) 
FROM 
(
    SELECT 
    @thisMonth := 0, 
    @runningTotal := 0 
) AS variableInit, 
(
    SELECT 
     order_date, 
     COUNT(*) AS distinctOrders, 
     COUNT(DISTINCT customer_id) AS distinctCustomers, 
     GROUP_CONCAT(DISTINCT customer_id ASC) AS customerIDs 
    FROM orders 

    GROUP BY order_date ASC 
) AS ordersPerDate 

最後把它清理乾淨,包裹在另一個子查詢只返回所需的,而不是內部變量行

分組對各天

SELECT 
    collatedData.order_date, 
    collatedData.ordersInThisMonth AS count_orders, 
    collatedData.distinctCustomers AS count_customers, 
    collatedData.customerIDs AS customer_ids 
FROM (

    SELECT 
     ordersPerDate.*, 
     IF(
      MONTH(ordersPerDate.order_date)[email protected], 
      @runningTotal := @runningTotal+ordersPerDate.distinctOrders, 
      @runningTotal := 0 
     ) AS ordersInThisMonth, 
     @thisMonth := MONTH(ordersPerDate.order_date) 
    FROM 
    (
     SELECT 
     @thisMonth := 0, 
     @runningTotal := 0 
    ) AS variableInit, 
    (
     SELECT 
      order_date, 
      COUNT(*) AS distinctOrders, 
      COUNT(DISTINCT customer_id) AS distinctCustomers, 
      GROUP_CONCAT(DISTINCT customer_id) AS customerIDs 
     FROM orders 

     GROUP BY order_date ASC 
    ) AS ordersPerDate 
) AS collatedData 

現在終於繼從OP,最終產品

其他信息

分組上個日曆月

// Top level will sanitise the output 
SELECT 
    collatedData.orderYear, 
    collatedData.orderMonth, 
    collatedData.distinctOrders, 
    collatedData.ordersInThisMonth AS count_orders, 
    collatedData.distinctCustomers AS count_customers, 
    collatedData.customerIDs AS customer_ids 
FROM (
    // This level up will iterate through calculating running totals 
    SELECT 
     ordersPerDate.*, 
     IF(
      (ordersPerDate.orderYear,ordersPerDate.orderMonth) = (@thisYear,@thisMonth), 
      @runningTotal := @runningTotal+ordersPerDate.distinctOrders*ordersPerDate.distinctCustomers, 
      @runningTotal := 0 
     ) AS ordersInThisMonth, 
     @thisMonth := ordersPerDate.orderMonth, 
     @thisYear := ordersPerDate.orderYear 
    FROM 
    (
     SELECT 
     @thisMonth := 0, 
     @thisYear := 0, 
     @runningTotal := 0 
    ) AS variableInit, 
    (
     // Next level up will collate this to get per year, month, and per number of orders 
     SELECT 
      ordersPerDatePerUser.orderYear, 
      ordersPerDatePerUser.orderMonth, 
      ordersPerDatePerUser.distinctOrders, 
      COUNT(DISTINCT ordersPerDatePerUser.customer_id) AS distinctCustomers, 
      GROUP_CONCAT(ordersPerDatePerUser.customer_id) AS customerIDs 
     FROM (
      // Inner query will get the number of orders for each year, month, and customer 
      SELECT 
       YEAR(order_date) AS orderYear, 
       MONTH(order_date) AS orderMonth, 
       customer_id, 
       COUNT(*) AS distinctOrders 
      FROM orders 
      GROUP BY orderYear ASC, orderMonth ASC, customer_id ASC 
     ) AS ordersPerDatePerUser 
     GROUP BY 
      ordersPerDatePerUser.orderYear ASC, 
      ordersPerDatePerUser.orderMonth ASC, 
      ordersPerDatePerUser.distinctOrders DESC 
    ) AS ordersPerDate 


) AS collatedData 
+0

感謝您的想法!但它不會產生我正在尋找的那種數據。如上所述添加了PHP/mysql解決方法。不過,我想有一種更優雅的方式只使用SQL解決這個問題? – Cord 2012-02-21 12:44:41

+0

輸出有什麼問題?這應該產生你所要求的 - 不能幫助,如果你不讓我知道它如何不按預期工作:) – 2012-02-21 12:48:22

+0

嗨西蒙,查詢按天分組,而不是按月。已經添加了一個有效的PHP解決方法,但是在一個查詢中使用它會很好。再次感謝! – Cord 2012-02-21 20:43:22

0
SELECT 
    substr(order_date,1,7) AS order_period, 
    count(*) AS number_of_orders, 
    count(DISTINCT orders.customer_id) AS number_of_customers, 
    GROUP_CONCAT(DISTINCT orders.customer_id) AS customers 
FROM orders 
GROUP BY substr(order_date,1,7) 
+0

很好的解決方案,給出了每月訂單和客戶總數的總和,但是我想要的是現在 - 每月:有多少客戶訂購了一次,多少次是兩次等等。 – Cord 2012-02-21 12:20:52

相關問題