我有这样的表格订单:
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']);
}
}
答案 0 :(得分: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)=@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
答案 1 :(得分: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)