我有一个这样的表订单:
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']);
}
}
最佳答案
一个好的起点是
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)=@thisMonth,
@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)=@thisMonth,
@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
关于mysql - 一段时间内的累计计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9376232/