Хорошей отправной точкой является
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
Это даст вам дату_заказа, количество заказов на эту дату, количество клиентов на эту дату и список идентификаторов клиентов на эту дату.
Просто рассмотрим способ подсчета ежемесячно.Итак, взглянув вперёд, я использовал подзапрос для подсчета по ходу дела
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