|
|
|
@ -15,12 +15,14 @@ export class StatisticsService {
|
|
|
|
orderItemRepository: Repository<OrderItem>;
|
|
|
|
orderItemRepository: Repository<OrderItem>;
|
|
|
|
|
|
|
|
|
|
|
|
async getOrderStatistics(params: OrderStatisticsParams) {
|
|
|
|
async getOrderStatistics(params: OrderStatisticsParams) {
|
|
|
|
const { startDate, endDate, siteId } = params;
|
|
|
|
const { startDate, endDate, siteId ,grouping} = params;
|
|
|
|
// const keywords = keyword ? keyword.split(' ').filter(Boolean) : [];
|
|
|
|
// const keywords = keyword ? keyword.split(' ').filter(Boolean) : [];
|
|
|
|
const start = dayjs(startDate).format('YYYY-MM-DD');
|
|
|
|
const start = dayjs(startDate).format('YYYY-MM-DD');
|
|
|
|
const end = dayjs(endDate).add(1, 'd').format('YYYY-MM-DD');
|
|
|
|
const end = dayjs(endDate).add(1, 'd').format('YYYY-MM-DD');
|
|
|
|
let sql = `
|
|
|
|
|
|
|
|
WITH first_order AS (
|
|
|
|
let sql = '';
|
|
|
|
|
|
|
|
if (!grouping || grouping === 'day') {
|
|
|
|
|
|
|
|
sql = `WITH first_order AS (
|
|
|
|
SELECT customer_email, MIN(date_paid) AS first_purchase_date
|
|
|
|
SELECT customer_email, MIN(date_paid) AS first_purchase_date
|
|
|
|
FROM \`order\`
|
|
|
|
FROM \`order\`
|
|
|
|
GROUP BY customer_email
|
|
|
|
GROUP BY customer_email
|
|
|
|
@ -214,6 +216,393 @@ export class StatisticsService {
|
|
|
|
dt.can_total_orders
|
|
|
|
dt.can_total_orders
|
|
|
|
ORDER BY d.order_date DESC;
|
|
|
|
ORDER BY d.order_date DESC;
|
|
|
|
`;
|
|
|
|
`;
|
|
|
|
|
|
|
|
}else if (grouping === 'week') {
|
|
|
|
|
|
|
|
sql = `WITH first_order AS (
|
|
|
|
|
|
|
|
SELECT customer_email, MIN(date_paid) AS first_purchase_date
|
|
|
|
|
|
|
|
FROM \`order\`
|
|
|
|
|
|
|
|
GROUP BY customer_email
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
weekly_orders AS (
|
|
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
|
|
o.id AS order_id,
|
|
|
|
|
|
|
|
DATE_FORMAT(o.date_paid, '%Y-%u') AS order_date,
|
|
|
|
|
|
|
|
o.customer_email,
|
|
|
|
|
|
|
|
o.total,
|
|
|
|
|
|
|
|
o.source_type,
|
|
|
|
|
|
|
|
o.utm_source,
|
|
|
|
|
|
|
|
o.siteId,
|
|
|
|
|
|
|
|
CASE
|
|
|
|
|
|
|
|
WHEN o.date_paid = f.first_purchase_date THEN 'first_purchase'
|
|
|
|
|
|
|
|
ELSE 'repeat_purchase'
|
|
|
|
|
|
|
|
END AS purchase_type,
|
|
|
|
|
|
|
|
CASE
|
|
|
|
|
|
|
|
WHEN o.source_type = 'utm' AND o.utm_source = 'google' THEN 'cpc'
|
|
|
|
|
|
|
|
ELSE 'non_cpc'
|
|
|
|
|
|
|
|
END AS order_type,
|
|
|
|
|
|
|
|
MAX(CASE WHEN oi.name LIKE '%zyn%' THEN 'zyn' ELSE 'non_zyn' END) AS zyn_type,
|
|
|
|
|
|
|
|
MAX(CASE WHEN oi.name LIKE '%yoone%' THEN 'yoone' ELSE 'non_yoone' END) AS yoone_type,
|
|
|
|
|
|
|
|
MAX(CASE WHEN oi.name LIKE '%zex%' THEN 'zex' ELSE 'non_zex' END) AS zex_type
|
|
|
|
|
|
|
|
FROM \`order\` o
|
|
|
|
|
|
|
|
LEFT JOIN first_order f ON o.customer_email = f.customer_email
|
|
|
|
|
|
|
|
LEFT JOIN order_item oi ON o.id = oi.orderId
|
|
|
|
|
|
|
|
WHERE o.date_paid IS NOT NULL
|
|
|
|
|
|
|
|
AND o.date_paid >= '${start}' AND o.date_paid < '${end}'
|
|
|
|
|
|
|
|
AND o.status IN ('processing','completed')
|
|
|
|
|
|
|
|
GROUP BY o.id, o.date_paid, o.customer_email, o.total, o.source_type, o.siteId, o.utm_source
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
order_sales_summary AS (
|
|
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
|
|
orderId,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%zyn%' THEN quantity ELSE 0 END) AS zyn_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' THEN quantity ELSE 0 END) AS yoone_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%zex%' THEN quantity ELSE 0 END) AS zex_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND isPackage = 1 THEN quantity ELSE 0 END) AS yoone_G_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND isPackage = 0 THEN quantity ELSE 0 END) AS yoone_S_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%3%' THEN quantity ELSE 0 END) AS yoone_3_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%6%' THEN quantity ELSE 0 END) AS yoone_6_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%9%' THEN quantity ELSE 0 END) AS yoone_9_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%12%' THEN quantity ELSE 0 END) AS yoone_12_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%15%' THEN quantity ELSE 0 END) AS yoone_15_quantity
|
|
|
|
|
|
|
|
FROM order_sale
|
|
|
|
|
|
|
|
GROUP BY orderId
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
order_items_summary AS (
|
|
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
|
|
orderId,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%zyn%' THEN total + total_tax ELSE 0 END) AS zyn_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' THEN total + total_tax ELSE 0 END) AS yoone_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%zex%' THEN total + total_tax ELSE 0 END) AS zex_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%package%' THEN total + total_tax ELSE 0 END) AS yoone_G_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name NOT LIKE '%package%' THEN total + total_tax ELSE 0 END) AS yoone_S_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%3%' THEN total + total_tax ELSE 0 END) AS yoone_3_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%6%' THEN total + total_tax ELSE 0 END) AS yoone_6_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%9%' THEN total + total_tax ELSE 0 END) AS yoone_9_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%12%' THEN total + total_tax ELSE 0 END) AS yoone_12_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%15%' THEN total + total_tax ELSE 0 END) AS yoone_15_amount
|
|
|
|
|
|
|
|
FROM order_item
|
|
|
|
|
|
|
|
GROUP BY orderId
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
weekly_totals AS (
|
|
|
|
|
|
|
|
SELECT order_date, SUM(total) AS total_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN siteId = 1 THEN total ELSE 0 END) AS togo_total_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN siteId = 2 THEN total ELSE 0 END) AS can_total_amount,
|
|
|
|
|
|
|
|
COUNT(DISTINCT order_id) AS total_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN siteId = 1 THEN order_id END) AS togo_total_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN siteId = 2 THEN order_id END) AS can_total_orders,
|
|
|
|
|
|
|
|
SUM(CASE WHEN purchase_type = 'first_purchase' THEN total ELSE 0 END) AS first_purchase_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN purchase_type = 'repeat_purchase' THEN total ELSE 0 END) AS repeat_purchase_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN order_type = 'cpc' THEN total ELSE 0 END) AS cpc_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN order_type = 'non_cpc' THEN total ELSE 0 END) AS non_cpc_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN zyn_type = 'zyn' AND order_type = 'cpc' THEN total ELSE 0 END) AS zyn_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN zyn_type = 'zyn' AND order_type = 'non_cpc' THEN total ELSE 0 END) AS non_zyn_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN yoone_type = 'yoone' AND order_type = 'cpc' THEN total ELSE 0 END) AS yoone_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN yoone_type = 'yoone' AND order_type = 'non_cpc' THEN total ELSE 0 END) AS non_yoone_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN zex_type = 'zex' AND order_type = 'cpc' THEN total ELSE 0 END) AS zex_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN zex_type = 'zex' AND order_type = 'non_cpc' THEN total ELSE 0 END) AS non_zex_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN source_type = 'typein' THEN total ELSE 0 END) AS direct_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN source_type = 'organic' THEN total ELSE 0 END) AS organic_total
|
|
|
|
|
|
|
|
FROM weekly_orders
|
|
|
|
|
|
|
|
GROUP BY order_date
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
|
|
wt.order_date,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.purchase_type = 'first_purchase' THEN wo.order_id END) AS first_purchase_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.purchase_type = 'repeat_purchase' THEN wo.order_id END) AS repeat_purchase_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.order_type = 'cpc' THEN wo.order_id END) AS cpc_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.order_type = 'cpc' AND wo.siteId = 1 THEN wo.order_id END) AS togo_cpc_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.order_type = 'cpc' AND wo.siteId = 2 THEN wo.order_id END) AS can_cpc_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.order_type = 'non_cpc' THEN wo.order_id END) AS non_cpc_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.order_type = 'non_cpc' AND wo.siteId = 1 THEN wo.order_id END) AS non_togo_cpc_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.order_type = 'non_cpc' AND wo.siteId = 2 THEN wo.order_id END) AS non_can_cpc_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.zyn_type = 'zyn' AND wo.order_type = 'cpc' THEN wo.order_id END) AS zyn_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.zyn_type = 'zyn' AND wo.order_type = 'non_cpc' THEN wo.order_id END) AS non_zyn_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.yoone_type = 'yoone' AND wo.order_type = 'cpc' THEN wo.order_id END) AS yoone_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.yoone_type = 'yoone' AND wo.order_type = 'non_cpc' THEN wo.order_id END) AS non_yoone_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.zex_type = 'zex' AND wo.order_type = 'cpc' THEN wo.order_id END) AS zex_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.zex_type = 'zex' AND wo.order_type = 'non_cpc' THEN wo.order_id END) AS non_zex_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.source_type = 'typein' THEN wo.order_id END) AS direct_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN wo.source_type = 'organic' THEN wo.order_id END) AS organic_orders,
|
|
|
|
|
|
|
|
wt.total_orders,
|
|
|
|
|
|
|
|
wt.togo_total_orders,
|
|
|
|
|
|
|
|
wt.can_total_orders,
|
|
|
|
|
|
|
|
wt.total_amount,
|
|
|
|
|
|
|
|
wt.togo_total_amount,
|
|
|
|
|
|
|
|
wt.can_total_amount,
|
|
|
|
|
|
|
|
wt.first_purchase_total,
|
|
|
|
|
|
|
|
wt.repeat_purchase_total,
|
|
|
|
|
|
|
|
wt.cpc_total,
|
|
|
|
|
|
|
|
wt.non_cpc_total,
|
|
|
|
|
|
|
|
wt.zyn_total,
|
|
|
|
|
|
|
|
wt.non_zyn_total,
|
|
|
|
|
|
|
|
wt.yoone_total,
|
|
|
|
|
|
|
|
wt.non_yoone_total,
|
|
|
|
|
|
|
|
wt.zex_total,
|
|
|
|
|
|
|
|
wt.non_zex_total,
|
|
|
|
|
|
|
|
wt.direct_total,
|
|
|
|
|
|
|
|
wt.organic_total,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.zyn_quantity), 0) AS zyn_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'cpc' THEN os.zyn_quantity ELSE 0 END) AS cpc_zyn_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.zyn_quantity ELSE 0 END) AS non_cpc_zyn_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_quantity), 0) AS yoone_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_quantity ELSE 0 END) AS cpc_yoone_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_quantity ELSE 0 END) AS non_cpc_yoone_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_G_quantity), 0) AS yoone_G_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_G_quantity ELSE 0 END) AS cpc_yoone_G_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_G_quantity ELSE 0 END) AS non_cpc_yoone_G_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_S_quantity), 0) AS yoone_S_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_S_quantity ELSE 0 END) AS cpc_yoone_S_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_S_quantity ELSE 0 END) AS non_cpc_yoone_S_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_3_quantity), 0) AS yoone_3_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_3_quantity ELSE 0 END) AS cpc_yoone_3_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_3_quantity ELSE 0 END) AS non_cpc_yoone_3_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_6_quantity), 0) AS yoone_6_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_6_quantity ELSE 0 END) AS cpc_yoone_6_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_6_quantity ELSE 0 END) AS non_cpc_yoone_6_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_9_quantity), 0) AS yoone_9_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_9_quantity ELSE 0 END) AS cpc_yoone_9_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_9_quantity ELSE 0 END) AS non_cpc_yoone_9_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_12_quantity), 0) AS yoone_12_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_12_quantity ELSE 0 END) AS cpc_yoone_12_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_12_quantity ELSE 0 END) AS non_cpc_yoone_12_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_15_quantity), 0) AS yoone_15_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'cpc' THEN os.yoone_15_quantity ELSE 0 END) AS cpc_yoone_15_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.yoone_15_quantity ELSE 0 END) AS non_cpc_yoone_15_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.zex_quantity), 0) AS zex_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'cpc' THEN os.zex_quantity ELSE 0 END) AS cpc_zex_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN wo.order_type = 'non_cpc' THEN os.zex_quantity ELSE 0 END) AS non_cpc_zex_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.zyn_amount), 0) AS zyn_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_amount), 0) AS yoone_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.zex_amount), 0) AS zex_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_G_amount), 0) AS yoone_G_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_S_amount), 0) AS yoone_S_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_3_amount), 0) AS yoone_3_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_6_amount), 0) AS yoone_6_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_9_amount), 0) AS yoone_9_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_12_amount), 0) AS yoone_12_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_15_amount), 0) AS yoone_15_amount,
|
|
|
|
|
|
|
|
ROUND(COALESCE(wt.total_amount / wt.total_orders, 0), 2) AS avg_total_amount,
|
|
|
|
|
|
|
|
ROUND(COALESCE(wt.togo_total_amount / wt.togo_total_orders, 0), 2) AS avg_togo_total_amount,
|
|
|
|
|
|
|
|
ROUND(COALESCE(wt.can_total_amount / wt.can_total_orders, 0), 2) AS avg_can_total_amount
|
|
|
|
|
|
|
|
FROM weekly_orders wo
|
|
|
|
|
|
|
|
LEFT JOIN weekly_totals wt ON wo.order_date = wt.order_date
|
|
|
|
|
|
|
|
LEFT JOIN order_sales_summary os ON wo.order_id = os.orderId
|
|
|
|
|
|
|
|
LEFT JOIN order_items_summary oi ON wo.order_id = oi.orderId
|
|
|
|
|
|
|
|
GROUP BY
|
|
|
|
|
|
|
|
wt.order_date,
|
|
|
|
|
|
|
|
wt.total_amount,
|
|
|
|
|
|
|
|
wt.togo_total_amount,
|
|
|
|
|
|
|
|
wt.can_total_amount,
|
|
|
|
|
|
|
|
wt.first_purchase_total,
|
|
|
|
|
|
|
|
wt.repeat_purchase_total,
|
|
|
|
|
|
|
|
wt.cpc_total,
|
|
|
|
|
|
|
|
wt.non_cpc_total,
|
|
|
|
|
|
|
|
wt.zyn_total,
|
|
|
|
|
|
|
|
wt.non_zyn_total,
|
|
|
|
|
|
|
|
wt.yoone_total,
|
|
|
|
|
|
|
|
wt.non_yoone_total,
|
|
|
|
|
|
|
|
wt.zex_total,
|
|
|
|
|
|
|
|
wt.non_zex_total,
|
|
|
|
|
|
|
|
wt.direct_total,
|
|
|
|
|
|
|
|
wt.organic_total,
|
|
|
|
|
|
|
|
wt.total_orders,
|
|
|
|
|
|
|
|
wt.togo_total_orders,
|
|
|
|
|
|
|
|
wt.can_total_orders
|
|
|
|
|
|
|
|
ORDER BY wt.order_date DESC;
|
|
|
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
}else if (grouping === 'month') {
|
|
|
|
|
|
|
|
sql = `WITH first_order AS (
|
|
|
|
|
|
|
|
SELECT customer_email, MIN(date_paid) AS first_purchase_date
|
|
|
|
|
|
|
|
FROM \`order\`
|
|
|
|
|
|
|
|
GROUP BY customer_email
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
monthly_orders AS (
|
|
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
|
|
o.id AS order_id,
|
|
|
|
|
|
|
|
DATE_FORMAT(o.date_paid, '%Y-%m') AS order_date,
|
|
|
|
|
|
|
|
o.customer_email,
|
|
|
|
|
|
|
|
o.total,
|
|
|
|
|
|
|
|
o.source_type,
|
|
|
|
|
|
|
|
o.utm_source,
|
|
|
|
|
|
|
|
o.siteId,
|
|
|
|
|
|
|
|
CASE
|
|
|
|
|
|
|
|
WHEN o.date_paid = f.first_purchase_date THEN 'first_purchase'
|
|
|
|
|
|
|
|
ELSE 'repeat_purchase'
|
|
|
|
|
|
|
|
END AS purchase_type,
|
|
|
|
|
|
|
|
CASE
|
|
|
|
|
|
|
|
WHEN o.source_type = 'utm' AND o.utm_source = 'google' THEN 'cpc'
|
|
|
|
|
|
|
|
ELSE 'non_cpc'
|
|
|
|
|
|
|
|
END AS order_type,
|
|
|
|
|
|
|
|
MAX(CASE WHEN oi.name LIKE '%zyn%' THEN 'zyn' ELSE 'non_zyn' END) AS zyn_type,
|
|
|
|
|
|
|
|
MAX(CASE WHEN oi.name LIKE '%yoone%' THEN 'yoone' ELSE 'non_yoone' END) AS yoone_type,
|
|
|
|
|
|
|
|
MAX(CASE WHEN oi.name LIKE '%zex%' THEN 'zex' ELSE 'non_zex' END) AS zex_type
|
|
|
|
|
|
|
|
FROM \`order\` o
|
|
|
|
|
|
|
|
LEFT JOIN first_order f ON o.customer_email = f.customer_email
|
|
|
|
|
|
|
|
LEFT JOIN order_item oi ON o.id = oi.orderId
|
|
|
|
|
|
|
|
WHERE o.date_paid IS NOT NULL
|
|
|
|
|
|
|
|
AND o.date_paid >= '${start}' AND o.date_paid < '${end}'
|
|
|
|
|
|
|
|
AND o.status IN ('processing','completed')
|
|
|
|
|
|
|
|
GROUP BY o.id, o.date_paid, o.customer_email, o.total, o.source_type, o.siteId, o.utm_source
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
order_sales_summary AS (
|
|
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
|
|
orderId,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%zyn%' THEN quantity ELSE 0 END) AS zyn_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' THEN quantity ELSE 0 END) AS yoone_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%zex%' THEN quantity ELSE 0 END) AS zex_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND isPackage = 1 THEN quantity ELSE 0 END) AS yoone_G_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND isPackage = 0 THEN quantity ELSE 0 END) AS yoone_S_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%3%' THEN quantity ELSE 0 END) AS yoone_3_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%6%' THEN quantity ELSE 0 END) AS yoone_6_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%9%' THEN quantity ELSE 0 END) AS yoone_9_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%12%' THEN quantity ELSE 0 END) AS yoone_12_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%15%' THEN quantity ELSE 0 END) AS yoone_15_quantity
|
|
|
|
|
|
|
|
FROM order_sale
|
|
|
|
|
|
|
|
GROUP BY orderId
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
order_items_summary AS (
|
|
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
|
|
orderId,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%zyn%' THEN total + total_tax ELSE 0 END) AS zyn_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' THEN total + total_tax ELSE 0 END) AS yoone_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%zex%' THEN total + total_tax ELSE 0 END) AS zex_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%package%' THEN total + total_tax ELSE 0 END) AS yoone_G_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name NOT LIKE '%package%' THEN total + total_tax ELSE 0 END) AS yoone_S_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%3%' THEN total + total_tax ELSE 0 END) AS yoone_3_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%6%' THEN total + total_tax ELSE 0 END) AS yoone_6_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%9%' THEN total + total_tax ELSE 0 END) AS yoone_9_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%12%' THEN total + total_tax ELSE 0 END) AS yoone_12_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%15%' THEN total + total_tax ELSE 0 END) AS yoone_15_amount
|
|
|
|
|
|
|
|
FROM order_item
|
|
|
|
|
|
|
|
GROUP BY orderId
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
monthly_totals AS (
|
|
|
|
|
|
|
|
SELECT order_date, SUM(total) AS total_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN siteId = 1 THEN total ELSE 0 END) AS togo_total_amount,
|
|
|
|
|
|
|
|
SUM(CASE WHEN siteId = 2 THEN total ELSE 0 END) AS can_total_amount,
|
|
|
|
|
|
|
|
COUNT(DISTINCT order_id) AS total_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN siteId = 1 THEN order_id END) AS togo_total_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN siteId = 2 THEN order_id END) AS can_total_orders,
|
|
|
|
|
|
|
|
SUM(CASE WHEN purchase_type = 'first_purchase' THEN total ELSE 0 END) AS first_purchase_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN purchase_type = 'repeat_purchase' THEN total ELSE 0 END) AS repeat_purchase_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN order_type = 'cpc' THEN total ELSE 0 END) AS cpc_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN order_type = 'non_cpc' THEN total ELSE 0 END) AS non_cpc_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN zyn_type = 'zyn' AND order_type = 'cpc' THEN total ELSE 0 END) AS zyn_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN zyn_type = 'zyn' AND order_type = 'non_cpc' THEN total ELSE 0 END) AS non_zyn_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN yoone_type = 'yoone' AND order_type = 'cpc' THEN total ELSE 0 END) AS yoone_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN yoone_type = 'yoone' AND order_type = 'non_cpc' THEN total ELSE 0 END) AS non_yoone_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN zex_type = 'zex' AND order_type = 'cpc' THEN total ELSE 0 END) AS zex_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN zex_type = 'zex' AND order_type = 'non_cpc' THEN total ELSE 0 END) AS non_zex_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN source_type = 'typein' THEN total ELSE 0 END) AS direct_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN source_type = 'organic' THEN total ELSE 0 END) AS organic_total
|
|
|
|
|
|
|
|
FROM monthly_orders
|
|
|
|
|
|
|
|
GROUP BY order_date
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
|
|
mt.order_date,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.purchase_type = 'first_purchase' THEN mo.order_id END) AS first_purchase_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.purchase_type = 'repeat_purchase' THEN mo.order_id END) AS repeat_purchase_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.order_type = 'cpc' THEN mo.order_id END) AS cpc_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.order_type = 'cpc' AND mo.siteId = 1 THEN mo.order_id END) AS togo_cpc_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.order_type = 'cpc' AND mo.siteId = 2 THEN mo.order_id END) AS can_cpc_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.order_type = 'non_cpc' THEN mo.order_id END) AS non_cpc_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.order_type = 'non_cpc' AND mo.siteId = 1 THEN mo.order_id END) AS non_togo_cpc_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.order_type = 'non_cpc' AND mo.siteId = 2 THEN mo.order_id END) AS non_can_cpc_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.zyn_type = 'zyn' AND mo.order_type = 'cpc' THEN mo.order_id END) AS zyn_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.zyn_type = 'zyn' AND mo.order_type = 'non_cpc' THEN mo.order_id END) AS non_zyn_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.yoone_type = 'yoone' AND mo.order_type = 'cpc' THEN mo.order_id END) AS yoone_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.yoone_type = 'yoone' AND mo.order_type = 'non_cpc' THEN mo.order_id END) AS non_yoone_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.zex_type = 'zex' AND mo.order_type = 'cpc' THEN mo.order_id END) AS zex_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.zex_type = 'zex' AND mo.order_type = 'non_cpc' THEN mo.order_id END) AS non_zex_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.source_type = 'typein' THEN mo.order_id END) AS direct_orders,
|
|
|
|
|
|
|
|
COUNT(DISTINCT CASE WHEN mo.source_type = 'organic' THEN mo.order_id END) AS organic_orders,
|
|
|
|
|
|
|
|
mt.total_orders,
|
|
|
|
|
|
|
|
mt.togo_total_orders,
|
|
|
|
|
|
|
|
mt.can_total_orders,
|
|
|
|
|
|
|
|
mt.total_amount,
|
|
|
|
|
|
|
|
mt.togo_total_amount,
|
|
|
|
|
|
|
|
mt.can_total_amount,
|
|
|
|
|
|
|
|
mt.first_purchase_total,
|
|
|
|
|
|
|
|
mt.repeat_purchase_total,
|
|
|
|
|
|
|
|
mt.cpc_total,
|
|
|
|
|
|
|
|
mt.non_cpc_total,
|
|
|
|
|
|
|
|
mt.zyn_total,
|
|
|
|
|
|
|
|
mt.non_zyn_total,
|
|
|
|
|
|
|
|
mt.yoone_total,
|
|
|
|
|
|
|
|
mt.non_yoone_total,
|
|
|
|
|
|
|
|
mt.zex_total,
|
|
|
|
|
|
|
|
mt.non_zex_total,
|
|
|
|
|
|
|
|
mt.direct_total,
|
|
|
|
|
|
|
|
mt.organic_total,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.zyn_quantity), 0) AS zyn_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'cpc' THEN os.zyn_quantity ELSE 0 END) AS cpc_zyn_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.zyn_quantity ELSE 0 END) AS non_cpc_zyn_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_quantity), 0) AS yoone_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_quantity ELSE 0 END) AS cpc_yoone_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_quantity ELSE 0 END) AS non_cpc_yoone_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_G_quantity), 0) AS yoone_G_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_G_quantity ELSE 0 END) AS cpc_yoone_G_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_G_quantity ELSE 0 END) AS non_cpc_yoone_G_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_S_quantity), 0) AS yoone_S_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_S_quantity ELSE 0 END) AS cpc_yoone_S_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_S_quantity ELSE 0 END) AS non_cpc_yoone_S_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_3_quantity), 0) AS yoone_3_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_3_quantity ELSE 0 END) AS cpc_yoone_3_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_3_quantity ELSE 0 END) AS non_cpc_yoone_3_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_6_quantity), 0) AS yoone_6_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_6_quantity ELSE 0 END) AS cpc_yoone_6_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_6_quantity ELSE 0 END) AS non_cpc_yoone_6_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_9_quantity), 0) AS yoone_9_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_9_quantity ELSE 0 END) AS cpc_yoone_9_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_9_quantity ELSE 0 END) AS non_cpc_yoone_9_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_12_quantity), 0) AS yoone_12_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_12_quantity ELSE 0 END) AS cpc_yoone_12_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_12_quantity ELSE 0 END) AS non_cpc_yoone_12_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.yoone_15_quantity), 0) AS yoone_15_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'cpc' THEN os.yoone_15_quantity ELSE 0 END) AS cpc_yoone_15_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.yoone_15_quantity ELSE 0 END) AS non_cpc_yoone_15_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(os.zex_quantity), 0) AS zex_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'cpc' THEN os.zex_quantity ELSE 0 END) AS cpc_zex_quantity,
|
|
|
|
|
|
|
|
SUM(CASE WHEN mo.order_type = 'non_cpc' THEN os.zex_quantity ELSE 0 END) AS non_cpc_zex_quantity,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.zyn_amount), 0) AS zyn_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_amount), 0) AS yoone_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.zex_amount), 0) AS zex_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_G_amount), 0) AS yoone_G_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_S_amount), 0) AS yoone_S_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_3_amount), 0) AS yoone_3_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_6_amount), 0) AS yoone_6_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_9_amount), 0) AS yoone_9_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_12_amount), 0) AS yoone_12_amount,
|
|
|
|
|
|
|
|
COALESCE(SUM(oi.yoone_15_amount), 0) AS yoone_15_amount,
|
|
|
|
|
|
|
|
ROUND(COALESCE(mt.total_amount / mt.total_orders, 0), 2) AS avg_total_amount,
|
|
|
|
|
|
|
|
ROUND(COALESCE(mt.togo_total_amount / mt.togo_total_orders, 0), 2) AS avg_togo_total_amount,
|
|
|
|
|
|
|
|
ROUND(COALESCE(mt.can_total_amount / mt.can_total_orders, 0), 2) AS avg_can_total_amount
|
|
|
|
|
|
|
|
FROM monthly_orders mo
|
|
|
|
|
|
|
|
LEFT JOIN monthly_totals mt ON mo.order_date = mt.order_date
|
|
|
|
|
|
|
|
LEFT JOIN order_sales_summary os ON mo.order_id = os.orderId
|
|
|
|
|
|
|
|
LEFT JOIN order_items_summary oi ON mo.order_id = oi.orderId
|
|
|
|
|
|
|
|
GROUP BY
|
|
|
|
|
|
|
|
mt.order_date,
|
|
|
|
|
|
|
|
mt.total_amount,
|
|
|
|
|
|
|
|
mt.togo_total_amount,
|
|
|
|
|
|
|
|
mt.can_total_amount,
|
|
|
|
|
|
|
|
mt.first_purchase_total,
|
|
|
|
|
|
|
|
mt.repeat_purchase_total,
|
|
|
|
|
|
|
|
mt.cpc_total,
|
|
|
|
|
|
|
|
mt.non_cpc_total,
|
|
|
|
|
|
|
|
mt.zyn_total,
|
|
|
|
|
|
|
|
mt.non_zyn_total,
|
|
|
|
|
|
|
|
mt.yoone_total,
|
|
|
|
|
|
|
|
mt.non_yoone_total,
|
|
|
|
|
|
|
|
mt.zex_total,
|
|
|
|
|
|
|
|
mt.non_zex_total,
|
|
|
|
|
|
|
|
mt.direct_total,
|
|
|
|
|
|
|
|
mt.organic_total,
|
|
|
|
|
|
|
|
mt.total_orders,
|
|
|
|
|
|
|
|
mt.togo_total_orders,
|
|
|
|
|
|
|
|
mt.can_total_orders
|
|
|
|
|
|
|
|
ORDER BY mt.order_date DESC;
|
|
|
|
|
|
|
|
`;}
|
|
|
|
|
|
|
|
|
|
|
|
return this.orderRepository.query(sql);
|
|
|
|
return this.orderRepository.query(sql);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// async getOrderStatistics(params: OrderStatisticsParams) {
|
|
|
|
// async getOrderStatistics(params: OrderStatisticsParams) {
|
|
|
|
@ -656,10 +1045,10 @@ export class StatisticsService {
|
|
|
|
const offset = (current - 1) * pageSize;
|
|
|
|
const offset = (current - 1) * pageSize;
|
|
|
|
const countSql = `
|
|
|
|
const countSql = `
|
|
|
|
WITH product_list AS (
|
|
|
|
WITH product_list AS (
|
|
|
|
SELECT DISTINCT s.sku
|
|
|
|
SELECT DISTINCT s.productSku
|
|
|
|
FROM stock s
|
|
|
|
FROM stock s
|
|
|
|
LEFT JOIN stock_point sp ON s.stockPointId = sp.id
|
|
|
|
LEFT JOIN stock_point sp ON s.stockPointId = sp.id
|
|
|
|
LEFT JOIN product p ON s.sku = p.sku
|
|
|
|
LEFT JOIN product p ON s.productSku = p.sku
|
|
|
|
WHERE sp.ignore = FALSE
|
|
|
|
WHERE sp.ignore = FALSE
|
|
|
|
${countnameFilter}
|
|
|
|
${countnameFilter}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
@ -674,27 +1063,27 @@ export class StatisticsService {
|
|
|
|
const sql = `
|
|
|
|
const sql = `
|
|
|
|
WITH stock_summary AS (
|
|
|
|
WITH stock_summary AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
s.sku,
|
|
|
|
s.productSku,
|
|
|
|
JSON_ARRAYAGG(JSON_OBJECT('id', sp.id, 'quantity', s.quantity)) AS stockDetails,
|
|
|
|
JSON_ARRAYAGG(JSON_OBJECT('id', sp.id, 'quantity', s.quantity)) AS stockDetails,
|
|
|
|
SUM(s.quantity) AS totalStock,
|
|
|
|
SUM(s.quantity) AS totalStock,
|
|
|
|
SUM(CASE WHEN sp.inCanada THEN s.quantity ELSE 0 END) AS caTotalStock
|
|
|
|
SUM(CASE WHEN sp.inCanada THEN s.quantity ELSE 0 END) AS caTotalStock
|
|
|
|
FROM stock s
|
|
|
|
FROM stock s
|
|
|
|
JOIN stock_point sp ON s.stockPointId = sp.id
|
|
|
|
JOIN stock_point sp ON s.stockPointId = sp.id
|
|
|
|
WHERE sp.ignore = FALSE
|
|
|
|
WHERE sp.ignore = FALSE
|
|
|
|
GROUP BY s.sku
|
|
|
|
GROUP BY s.productSku
|
|
|
|
),
|
|
|
|
),
|
|
|
|
transfer_stock AS (
|
|
|
|
transfer_stock AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
ti.sku,
|
|
|
|
ti.productSku,
|
|
|
|
SUM(ti.quantity) AS transitStock
|
|
|
|
SUM(ti.quantity) AS transitStock
|
|
|
|
FROM transfer_item ti
|
|
|
|
FROM transfer_item ti
|
|
|
|
JOIN transfer t ON ti.transferId = t.id
|
|
|
|
JOIN transfer t ON ti.transferId = t.id
|
|
|
|
WHERE t.isCancel = FALSE AND t.isArrived = FALSE
|
|
|
|
WHERE t.isCancel = FALSE AND t.isArrived = FALSE
|
|
|
|
GROUP BY ti.sku
|
|
|
|
GROUP BY ti.productSku
|
|
|
|
),
|
|
|
|
),
|
|
|
|
30_sales_summary AS (
|
|
|
|
30_sales_summary AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
os.sku AS sku,
|
|
|
|
os.sku AS productSku,
|
|
|
|
SUM(os.quantity) AS totalSales
|
|
|
|
SUM(os.quantity) AS totalSales
|
|
|
|
FROM order_sale os
|
|
|
|
FROM order_sale os
|
|
|
|
JOIN \`order\` o ON os.orderId = o.id
|
|
|
|
JOIN \`order\` o ON os.orderId = o.id
|
|
|
|
@ -704,7 +1093,7 @@ export class StatisticsService {
|
|
|
|
),
|
|
|
|
),
|
|
|
|
15_sales_summary AS (
|
|
|
|
15_sales_summary AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
os.sku AS sku,
|
|
|
|
os.sku AS productSku,
|
|
|
|
2 * SUM(os.quantity) AS totalSales
|
|
|
|
2 * SUM(os.quantity) AS totalSales
|
|
|
|
FROM order_sale os
|
|
|
|
FROM order_sale os
|
|
|
|
JOIN \`order\` o ON os.orderId = o.id
|
|
|
|
JOIN \`order\` o ON os.orderId = o.id
|
|
|
|
@ -714,36 +1103,36 @@ export class StatisticsService {
|
|
|
|
),
|
|
|
|
),
|
|
|
|
sales_max_summary AS (
|
|
|
|
sales_max_summary AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
s30.sku AS sku,
|
|
|
|
s30.productSku AS productSku,
|
|
|
|
COALESCE(s30.totalSales, 0) AS totalSales_30,
|
|
|
|
COALESCE(s30.totalSales, 0) AS totalSales_30,
|
|
|
|
COALESCE(s15.totalSales, 0) AS totalSales_15,
|
|
|
|
COALESCE(s15.totalSales, 0) AS totalSales_15,
|
|
|
|
GREATEST(COALESCE(s30.totalSales, 0), COALESCE(s15.totalSales, 0)) AS maxSales
|
|
|
|
GREATEST(COALESCE(s30.totalSales, 0), COALESCE(s15.totalSales, 0)) AS maxSales
|
|
|
|
FROM 30_sales_summary s30
|
|
|
|
FROM 30_sales_summary s30
|
|
|
|
LEFT JOIN 15_sales_summary s15
|
|
|
|
LEFT JOIN 15_sales_summary s15
|
|
|
|
ON s30.sku = s15.sku
|
|
|
|
ON s30.productSku = s15.productSku
|
|
|
|
|
|
|
|
|
|
|
|
UNION ALL
|
|
|
|
UNION ALL
|
|
|
|
|
|
|
|
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
s15.sku AS sku,
|
|
|
|
s15.productSku AS productSku,
|
|
|
|
0 AS totalSales_30,
|
|
|
|
0 AS totalSales_30,
|
|
|
|
COALESCE(s15.totalSales, 0) AS totalSales_15,
|
|
|
|
COALESCE(s15.totalSales, 0) AS totalSales_15,
|
|
|
|
COALESCE(s15.totalSales, 0) AS maxSales
|
|
|
|
COALESCE(s15.totalSales, 0) AS maxSales
|
|
|
|
FROM 15_sales_summary s15
|
|
|
|
FROM 15_sales_summary s15
|
|
|
|
LEFT JOIN 30_sales_summary s30
|
|
|
|
LEFT JOIN 30_sales_summary s30
|
|
|
|
ON s30.sku = s15.sku
|
|
|
|
ON s30.productSku = s15.productSku
|
|
|
|
WHERE s30.sku IS NULL
|
|
|
|
WHERE s30.productSku IS NULL
|
|
|
|
),
|
|
|
|
),
|
|
|
|
product_name_summary AS (
|
|
|
|
product_name_summary AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
p.sku AS sku,
|
|
|
|
p.sku AS productSku,
|
|
|
|
COALESCE(MAX(os.name), MAX(p.name)) AS productName
|
|
|
|
COALESCE(MAX(os.name), MAX(p.name)) AS productName
|
|
|
|
FROM product p
|
|
|
|
FROM product p
|
|
|
|
LEFT JOIN order_sale os ON p.sku = os.sku
|
|
|
|
LEFT JOIN order_sale os ON p.sku = os.sku
|
|
|
|
GROUP BY p.sku
|
|
|
|
GROUP BY p.sku
|
|
|
|
)
|
|
|
|
)
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
ss.sku,
|
|
|
|
ss.productSku,
|
|
|
|
ss.stockDetails,
|
|
|
|
ss.stockDetails,
|
|
|
|
COALESCE(ts.transitStock, 0) AS transitStock,
|
|
|
|
COALESCE(ts.transitStock, 0) AS transitStock,
|
|
|
|
(COALESCE(ss.totalStock, 0) + COALESCE(ts.transitStock, 0)) AS totalStock,
|
|
|
|
(COALESCE(ss.totalStock, 0) + COALESCE(ts.transitStock, 0)) AS totalStock,
|
|
|
|
@ -761,9 +1150,9 @@ export class StatisticsService {
|
|
|
|
sales.maxSales * 4 AS restockQuantity,
|
|
|
|
sales.maxSales * 4 AS restockQuantity,
|
|
|
|
pns.productName
|
|
|
|
pns.productName
|
|
|
|
FROM stock_summary ss
|
|
|
|
FROM stock_summary ss
|
|
|
|
LEFT JOIN transfer_stock ts ON ss.sku = ts.sku
|
|
|
|
LEFT JOIN transfer_stock ts ON ss.productSku = ts.productSku
|
|
|
|
LEFT JOIN sales_max_summary sales ON ss.sku = sales.sku
|
|
|
|
LEFT JOIN sales_max_summary sales ON ss.productSku = sales.productSku
|
|
|
|
LEFT JOIN product_name_summary pns ON ss.sku = pns.sku
|
|
|
|
LEFT JOIN product_name_summary pns ON ss.productSku = pns.productSku
|
|
|
|
WHERE 1 = 1
|
|
|
|
WHERE 1 = 1
|
|
|
|
${nameFilter}
|
|
|
|
${nameFilter}
|
|
|
|
ORDER BY caAvailableDays
|
|
|
|
ORDER BY caAvailableDays
|
|
|
|
@ -791,10 +1180,10 @@ export class StatisticsService {
|
|
|
|
const offset = (current - 1) * pageSize;
|
|
|
|
const offset = (current - 1) * pageSize;
|
|
|
|
const countSql = `
|
|
|
|
const countSql = `
|
|
|
|
WITH product_list AS (
|
|
|
|
WITH product_list AS (
|
|
|
|
SELECT DISTINCT s.sku
|
|
|
|
SELECT DISTINCT s.productSku
|
|
|
|
FROM stock s
|
|
|
|
FROM stock s
|
|
|
|
LEFT JOIN stock_point sp ON s.stockPointId = sp.id
|
|
|
|
LEFT JOIN stock_point sp ON s.stockPointId = sp.id
|
|
|
|
LEFT JOIN product p ON s.sku = p.sku
|
|
|
|
LEFT JOIN product p ON s.productSku = p.sku
|
|
|
|
WHERE sp.ignore = FALSE
|
|
|
|
WHERE sp.ignore = FALSE
|
|
|
|
${countnameFilter}
|
|
|
|
${countnameFilter}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
@ -810,36 +1199,36 @@ export class StatisticsService {
|
|
|
|
const sql = `
|
|
|
|
const sql = `
|
|
|
|
WITH stock_summary AS (
|
|
|
|
WITH stock_summary AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
s.sku,
|
|
|
|
s.productSku,
|
|
|
|
SUM(s.quantity) AS totalStock
|
|
|
|
SUM(s.quantity) AS totalStock
|
|
|
|
FROM stock s
|
|
|
|
FROM stock s
|
|
|
|
JOIN stock_point sp ON s.stockPointId = sp.id
|
|
|
|
JOIN stock_point sp ON s.stockPointId = sp.id
|
|
|
|
WHERE sp.ignore = FALSE
|
|
|
|
WHERE sp.ignore = FALSE
|
|
|
|
GROUP BY s.sku
|
|
|
|
GROUP BY s.productSku
|
|
|
|
),
|
|
|
|
),
|
|
|
|
transfer_stock AS (
|
|
|
|
transfer_stock AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
ti.sku,
|
|
|
|
ti.productSku,
|
|
|
|
SUM(ti.quantity) AS transitStock
|
|
|
|
SUM(ti.quantity) AS transitStock
|
|
|
|
FROM transfer_item ti
|
|
|
|
FROM transfer_item ti
|
|
|
|
JOIN transfer t ON ti.transferId = t.id
|
|
|
|
JOIN transfer t ON ti.transferId = t.id
|
|
|
|
WHERE t.isCancel = FALSE AND t.isArrived = FALSE
|
|
|
|
WHERE t.isCancel = FALSE AND t.isArrived = FALSE
|
|
|
|
GROUP BY ti.sku
|
|
|
|
GROUP BY ti.productSku
|
|
|
|
),
|
|
|
|
),
|
|
|
|
b_sales_data_raw As (
|
|
|
|
b_sales_data_raw As (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
sr.sku,
|
|
|
|
sr.productSku,
|
|
|
|
DATE_FORMAT(sr.createdAt, '%Y-%m') AS month,
|
|
|
|
DATE_FORMAT(sr.createdAt, '%Y-%m') AS month,
|
|
|
|
SUM(sr.quantityChange) AS sales
|
|
|
|
SUM(sr.quantityChange) AS sales
|
|
|
|
FROM stock_record sr
|
|
|
|
FROM stock_record sr
|
|
|
|
JOIN stock_point sp ON sr.stockPointId = sp.id
|
|
|
|
JOIN stock_point sp ON sr.stockPointId = sp.id
|
|
|
|
WHERE sp.isB
|
|
|
|
WHERE sp.isB
|
|
|
|
AND sr.createdAt >= DATE_FORMAT(NOW() - INTERVAL 2 MONTH, '%Y-%m-01')
|
|
|
|
AND sr.createdAt >= DATE_FORMAT(NOW() - INTERVAL 2 MONTH, '%Y-%m-01')
|
|
|
|
GROUP BY sr.sku, month
|
|
|
|
GROUP BY sr.productSku, month
|
|
|
|
),
|
|
|
|
),
|
|
|
|
sales_data_raw AS (
|
|
|
|
sales_data_raw AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
os.sku AS sku,
|
|
|
|
os.sku AS productSku,
|
|
|
|
DATE_FORMAT(o.date_paid, '%Y-%m') AS month,
|
|
|
|
DATE_FORMAT(o.date_paid, '%Y-%m') AS month,
|
|
|
|
SUM(CASE WHEN DAY(o.date_paid) <= 10 THEN os.quantity ELSE 0 END) AS early_sales,
|
|
|
|
SUM(CASE WHEN DAY(o.date_paid) <= 10 THEN os.quantity ELSE 0 END) AS early_sales,
|
|
|
|
SUM(CASE WHEN DAY(o.date_paid) > 10 AND DAY(o.date_paid) <= 20 THEN os.quantity ELSE 0 END) AS mid_sales,
|
|
|
|
SUM(CASE WHEN DAY(o.date_paid) > 10 AND DAY(o.date_paid) <= 20 THEN os.quantity ELSE 0 END) AS mid_sales,
|
|
|
|
@ -852,7 +1241,7 @@ export class StatisticsService {
|
|
|
|
),
|
|
|
|
),
|
|
|
|
monthly_sales_summary AS (
|
|
|
|
monthly_sales_summary AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
sdr.sku,
|
|
|
|
sdr.productSku,
|
|
|
|
JSON_ARRAYAGG(
|
|
|
|
JSON_ARRAYAGG(
|
|
|
|
JSON_OBJECT(
|
|
|
|
JSON_OBJECT(
|
|
|
|
'month', sdr.month,
|
|
|
|
'month', sdr.month,
|
|
|
|
@ -863,12 +1252,12 @@ export class StatisticsService {
|
|
|
|
)
|
|
|
|
)
|
|
|
|
) AS sales_data
|
|
|
|
) AS sales_data
|
|
|
|
FROM sales_data_raw sdr
|
|
|
|
FROM sales_data_raw sdr
|
|
|
|
LEFT JOIN b_sales_data_raw b ON sdr.sku = b.sku AND sdr.month = b.month
|
|
|
|
LEFT JOIN b_sales_data_raw b ON sdr.productSku = b.productSku AND sdr.month = b.month
|
|
|
|
GROUP BY sdr.sku
|
|
|
|
GROUP BY sdr.productSku
|
|
|
|
),
|
|
|
|
),
|
|
|
|
sales_summary AS (
|
|
|
|
sales_summary AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
os.sku AS sku,
|
|
|
|
os.sku AS productSku,
|
|
|
|
SUM(CASE WHEN o.date_paid >= CURDATE() - INTERVAL 30 DAY THEN os.quantity ELSE 0 END) AS last_30_days_sales,
|
|
|
|
SUM(CASE WHEN o.date_paid >= CURDATE() - INTERVAL 30 DAY THEN os.quantity ELSE 0 END) AS last_30_days_sales,
|
|
|
|
SUM(CASE WHEN o.date_paid >= CURDATE() - INTERVAL 15 DAY THEN os.quantity ELSE 0 END) AS last_15_days_sales,
|
|
|
|
SUM(CASE WHEN o.date_paid >= CURDATE() - INTERVAL 15 DAY THEN os.quantity ELSE 0 END) AS last_15_days_sales,
|
|
|
|
SUM(CASE WHEN DATE_FORMAT(o.date_paid, '%Y-%m') = DATE_FORMAT(CURDATE() - INTERVAL 1 MONTH, '%Y-%m') THEN os.quantity ELSE 0 END) AS last_month_sales
|
|
|
|
SUM(CASE WHEN DATE_FORMAT(o.date_paid, '%Y-%m') = DATE_FORMAT(CURDATE() - INTERVAL 1 MONTH, '%Y-%m') THEN os.quantity ELSE 0 END) AS last_month_sales
|
|
|
|
@ -880,14 +1269,14 @@ export class StatisticsService {
|
|
|
|
),
|
|
|
|
),
|
|
|
|
product_name_summary AS (
|
|
|
|
product_name_summary AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
p.sku AS sku,
|
|
|
|
p.sku AS productSku,
|
|
|
|
COALESCE(MAX(os.name), MAX(p.name)) AS productName
|
|
|
|
COALESCE(MAX(os.name), MAX(p.name)) AS productName
|
|
|
|
FROM product p
|
|
|
|
FROM product p
|
|
|
|
LEFT JOIN order_sale os ON p.sku = os.sku
|
|
|
|
LEFT JOIN order_sale os ON p.sku = os.sku
|
|
|
|
GROUP BY p.sku
|
|
|
|
GROUP BY p.sku
|
|
|
|
)
|
|
|
|
)
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
ss.sku,
|
|
|
|
ss.productSku,
|
|
|
|
(COALESCE(ss.totalStock, 0) + COALESCE(ts.transitStock, 0)) AS totalStock,
|
|
|
|
(COALESCE(ss.totalStock, 0) + COALESCE(ts.transitStock, 0)) AS totalStock,
|
|
|
|
ms.sales_data AS monthlySalesData,
|
|
|
|
ms.sales_data AS monthlySalesData,
|
|
|
|
pns.productName,
|
|
|
|
pns.productName,
|
|
|
|
@ -900,10 +1289,10 @@ export class StatisticsService {
|
|
|
|
ELSE NULL
|
|
|
|
ELSE NULL
|
|
|
|
END AS stock_ratio
|
|
|
|
END AS stock_ratio
|
|
|
|
FROM stock_summary ss
|
|
|
|
FROM stock_summary ss
|
|
|
|
LEFT JOIN transfer_stock ts ON ss.sku = ts.sku
|
|
|
|
LEFT JOIN transfer_stock ts ON ss.productSku = ts.productSku
|
|
|
|
LEFT JOIN monthly_sales_summary ms ON ss.sku = ms.sku
|
|
|
|
LEFT JOIN monthly_sales_summary ms ON ss.productSku = ms.productSku
|
|
|
|
LEFT JOIN product_name_summary pns ON ss.sku = pns.sku
|
|
|
|
LEFT JOIN product_name_summary pns ON ss.productSku = pns.productSku
|
|
|
|
LEFT JOIN sales_summary ssum ON ss.sku = ssum.sku
|
|
|
|
LEFT JOIN sales_summary ssum ON ss.productSku = ssum.productSku
|
|
|
|
WHERE 1 = 1
|
|
|
|
WHERE 1 = 1
|
|
|
|
${nameFilter}
|
|
|
|
${nameFilter}
|
|
|
|
ORDER BY
|
|
|
|
ORDER BY
|
|
|
|
@ -933,7 +1322,8 @@ export class StatisticsService {
|
|
|
|
user_first_order AS (
|
|
|
|
user_first_order AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
customer_email,
|
|
|
|
customer_email,
|
|
|
|
DATE_FORMAT(MIN(date_paid), '%Y-%m') AS first_order_month
|
|
|
|
DATE_FORMAT(MIN(date_paid), '%Y-%m') AS first_order_month,
|
|
|
|
|
|
|
|
SUM(total) AS first_order_total
|
|
|
|
FROM \`order\`
|
|
|
|
FROM \`order\`
|
|
|
|
WHERE status IN ('processing', 'completed')
|
|
|
|
WHERE status IN ('processing', 'completed')
|
|
|
|
GROUP BY customer_email
|
|
|
|
GROUP BY customer_email
|
|
|
|
@ -946,7 +1336,7 @@ export class StatisticsService {
|
|
|
|
WHERE status IN ('processing', 'completed')
|
|
|
|
WHERE status IN ('processing', 'completed')
|
|
|
|
),
|
|
|
|
),
|
|
|
|
filtered_orders AS (
|
|
|
|
filtered_orders AS (
|
|
|
|
SELECT o.customer_email, o.order_month, u.first_order_month, c.start_month
|
|
|
|
SELECT o.customer_email, o.order_month, u.first_order_month,u.first_order_total, c.start_month
|
|
|
|
FROM order_months o
|
|
|
|
FROM order_months o
|
|
|
|
JOIN user_first_order u ON o.customer_email = u.customer_email
|
|
|
|
JOIN user_first_order u ON o.customer_email = u.customer_email
|
|
|
|
JOIN cutoff_months c ON 1=1
|
|
|
|
JOIN cutoff_months c ON 1=1
|
|
|
|
@ -958,14 +1348,16 @@ export class StatisticsService {
|
|
|
|
CASE
|
|
|
|
CASE
|
|
|
|
WHEN first_order_month < start_month THEN CONCAT('>', start_month)
|
|
|
|
WHEN first_order_month < start_month THEN CONCAT('>', start_month)
|
|
|
|
ELSE first_order_month
|
|
|
|
ELSE first_order_month
|
|
|
|
END AS first_order_month_group
|
|
|
|
END AS first_order_month_group,
|
|
|
|
|
|
|
|
first_order_total
|
|
|
|
FROM filtered_orders
|
|
|
|
FROM filtered_orders
|
|
|
|
),
|
|
|
|
),
|
|
|
|
final_counts AS (
|
|
|
|
final_counts AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
order_month,
|
|
|
|
order_month,
|
|
|
|
first_order_month_group,
|
|
|
|
first_order_month_group,
|
|
|
|
COUNT(*) AS order_count
|
|
|
|
COUNT(*) AS order_count,
|
|
|
|
|
|
|
|
SUM(first_order_total) AS total
|
|
|
|
FROM classified
|
|
|
|
FROM classified
|
|
|
|
GROUP BY order_month, first_order_month_group
|
|
|
|
GROUP BY order_month, first_order_month_group
|
|
|
|
)
|
|
|
|
)
|
|
|
|
@ -985,7 +1377,8 @@ export class StatisticsService {
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
customer_email,
|
|
|
|
customer_email,
|
|
|
|
DATE_FORMAT(date_paid, '%Y-%m') AS order_month,
|
|
|
|
DATE_FORMAT(date_paid, '%Y-%m') AS order_month,
|
|
|
|
date_paid
|
|
|
|
date_paid,
|
|
|
|
|
|
|
|
total
|
|
|
|
FROM \`order\`
|
|
|
|
FROM \`order\`
|
|
|
|
WHERE status IN ('processing', 'completed')
|
|
|
|
WHERE status IN ('processing', 'completed')
|
|
|
|
),
|
|
|
|
),
|
|
|
|
@ -998,7 +1391,8 @@ export class StatisticsService {
|
|
|
|
monthly_users AS (
|
|
|
|
monthly_users AS (
|
|
|
|
SELECT DISTINCT
|
|
|
|
SELECT DISTINCT
|
|
|
|
customer_email,
|
|
|
|
customer_email,
|
|
|
|
order_month
|
|
|
|
order_month,
|
|
|
|
|
|
|
|
total
|
|
|
|
FROM filtered_users
|
|
|
|
FROM filtered_users
|
|
|
|
),
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
@ -1011,11 +1405,12 @@ export class StatisticsService {
|
|
|
|
GROUP BY customer_email
|
|
|
|
GROUP BY customer_email
|
|
|
|
),
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
-- 标注每个用户每月是"新客户"还是"老客户"
|
|
|
|
-- 标注每个用户每月是“新客户”还是“老客户”
|
|
|
|
labeled_users AS (
|
|
|
|
labeled_users AS (
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
m.customer_email,
|
|
|
|
m.customer_email,
|
|
|
|
m.order_month,
|
|
|
|
m.order_month,
|
|
|
|
|
|
|
|
m.total,
|
|
|
|
CASE
|
|
|
|
CASE
|
|
|
|
WHEN f.first_order_month = m.order_month THEN 'new'
|
|
|
|
WHEN f.first_order_month = m.order_month THEN 'new'
|
|
|
|
ELSE 'returning'
|
|
|
|
ELSE 'returning'
|
|
|
|
@ -1029,7 +1424,9 @@ export class StatisticsService {
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
order_month,
|
|
|
|
order_month,
|
|
|
|
SUM(CASE WHEN customer_type = 'new' THEN 1 ELSE 0 END) AS new_user_count,
|
|
|
|
SUM(CASE WHEN customer_type = 'new' THEN 1 ELSE 0 END) AS new_user_count,
|
|
|
|
SUM(CASE WHEN customer_type = 'returning' THEN 1 ELSE 0 END) AS old_user_count
|
|
|
|
SUM(CASE WHEN customer_type = 'new' THEN total ELSE 0 END) AS new_user_total,
|
|
|
|
|
|
|
|
SUM(CASE WHEN customer_type = 'returning' THEN 1 ELSE 0 END) AS old_user_count,
|
|
|
|
|
|
|
|
SUM(CASE WHEN customer_type = 'returning' THEN total ELSE 0 END) AS old_user_total
|
|
|
|
FROM labeled_users
|
|
|
|
FROM labeled_users
|
|
|
|
GROUP BY order_month
|
|
|
|
GROUP BY order_month
|
|
|
|
),
|
|
|
|
),
|
|
|
|
@ -1056,12 +1453,14 @@ export class StatisticsService {
|
|
|
|
GROUP BY current_month
|
|
|
|
GROUP BY current_month
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
-- 最终结果:每月新客户,老客户,未来未复购客户
|
|
|
|
-- 最终结果:每月新客户、老客户、未来未复购客户
|
|
|
|
SELECT
|
|
|
|
SELECT
|
|
|
|
m.order_month,
|
|
|
|
m.order_month,
|
|
|
|
m.new_user_count,
|
|
|
|
m.new_user_count,
|
|
|
|
m.old_user_count,
|
|
|
|
m.old_user_count,
|
|
|
|
COALESCE(i.inactive_user_count, 0) AS inactive_user_count
|
|
|
|
COALESCE(i.inactive_user_count, 0) AS inactive_user_count,
|
|
|
|
|
|
|
|
m.new_user_total,
|
|
|
|
|
|
|
|
m.old_user_total
|
|
|
|
FROM monthly_new_old_counts m
|
|
|
|
FROM monthly_new_old_counts m
|
|
|
|
LEFT JOIN users_without_future_orders i
|
|
|
|
LEFT JOIN users_without_future_orders i
|
|
|
|
ON m.order_month = i.order_month
|
|
|
|
ON m.order_month = i.order_month
|
|
|
|
|