Skip to content

Instantly share code, notes, and snippets.

@CyberSecutor
Last active September 23, 2024 08:20
Show Gist options
  • Save CyberSecutor/cef29796f572c2a4b74be4a16440446c to your computer and use it in GitHub Desktop.
Save CyberSecutor/cef29796f572c2a4b74be4a16440446c to your computer and use it in GitHub Desktop.
magento2-sales-order-statistics
-- Sets the timezone for the current session.
SET time_zone = '+02:00';
-- Orders Per Year --
SELECT period_date as year, order_count, gross_revenue, ROUND(gross_revenue / order_count, 2) AS gross_aov
FROM (
SELECT
COUNT(*) AS order_count,
ROUND(SUM(base_grand_total), 2) AS gross_revenue,
DATE_FORMAT(o.created_at, '%Y') AS period_date
FROM sales_order o
WHERE o.created_at > '2000-01-01'
AND o.created_at <= CURDATE()
GROUP BY period_date
) t GROUP BY period_date ORDER BY period_date DESC;
-- Orders Per Day for Last Month --
SELECT period_date as day, order_count, gross_revenue, ROUND(gross_revenue / order_count, 2) AS gross_aov
FROM (
SELECT
COUNT(*) AS order_count,
ROUND(SUM(base_grand_total), 2) AS gross_revenue,
DATE_FORMAT(o.created_at, '%Y-%m-%d') AS period_date
FROM sales_order o
WHERE o.created_at > date_sub(CURDATE(), INTERVAL 1 MONTH)
AND o.created_at <= CURDATE()
GROUP BY period_date
) t GROUP BY period_date ORDER BY period_date DESC;
-- Orders Per Day for Last Month with Month over Month compare --
SELECT period_date as day,
order_count,
gross_revenue,
ROUND(gross_revenue / order_count, 2) AS gross_aov,
o_mom.mom_order_count as mom_count,
DATE_FORMAT(date_sub(created_date, INTERVAL 28 DAY), '%Y-%m-%d %W') as mom_date,
ROUND((order_count / o_mom.mom_order_count) * 100, 1 ) as mom_increase_perc
FROM (
SELECT
COUNT(*) AS order_count,
ROUND(SUM(base_grand_total), 2) AS gross_revenue,
DATE_FORMAT(o.created_at, '%Y-%m-%d %W') AS period_date,
DATE(o.created_at) AS created_date
FROM sales_order o
WHERE o.created_at > date_sub(CURDATE(), INTERVAL 1 MONTH)
AND o.created_at <= NOW()
GROUP BY period_date, created_date
) t,
LATERAL
(
SELECT
COUNT(*) AS mom_order_count
FROM sales_order o_mom
WHERE DATE(o_mom.created_at) = DATE(date_sub(created_date, INTERVAL 28 DAY))
) as o_mom
ORDER BY period_date DESC;
-- Orders Per Day for Last Month with Month over Month compare and a percentage for new customers --
SELECT period_date as day,
order_count,
gross_revenue,
ROUND(gross_revenue / order_count, 2) AS gross_aov,
DATE_FORMAT(date_sub(created_date, INTERVAL 28 DAY), '%Y-%m-%d %W') as mom_date,
o_mom.mom_order_count as mom_count,
ROUND(order_count / o_mom.mom_order_count * 100, 2) as mom_percent,
new_customers,
ROUND(new_customers / order_count * 100, 1) as new_customers_percent
FROM (
SELECT
COUNT(*) AS order_count,
ROUND(SUM(o.base_grand_total), 2) AS gross_revenue,
DATE_FORMAT(o.created_at, '%Y-%m-%d %W') AS period_date,
DATE(o.created_at) AS created_date,
SUM((SELECT IF(COUNT(so_customer.customer_id) = 1, 1, 0) FROM sales_order as so_customer
WHERE so_customer.customer_id = o.customer_id)) as new_customers
FROM sales_order o
WHERE o.created_at > date_sub(CURDATE(), INTERVAL 1 MONTH)
AND o.created_at <= NOW()
GROUP BY period_date, created_date
) t,
LATERAL
(
SELECT
COUNT(*) AS mom_order_count
FROM sales_order o_mom
WHERE DATE(o_mom.created_at) = DATE(date_sub(created_date, INTERVAL 28 DAY))
) as o_mom
ORDER BY period_date DESC;
-- Orders Per Hour for Last 24 Hrs with Week over Week count--
SELECT
period_date as hour,
order_count,
gross_revenue,
ROUND(gross_revenue / order_count, 2) AS gross_aov,
DATE_FORMAT(date_sub(period_date, INTERVAL 7 DAY), '%Y-%m-%d %H:00') as wow_date,
o_wow.wow_order_count as wow_count
FROM (
SELECT
COUNT(*) AS order_count,
ROUND(SUM(base_grand_total), 2) AS gross_revenue,
DATE_FORMAT(o.created_at, '%Y-%m-%d %H:00') AS period_date,
DATE(o.created_at) AS created_date
FROM sales_order o
WHERE o.created_at > date_sub(CURDATE(), INTERVAL 1 DAY)
GROUP BY period_date, created_date
) t,
LATERAL
(
SELECT
COUNT(*) AS wow_order_count
FROM sales_order o_wow
WHERE DATE_FORMAT(o_wow.created_at, '%Y-%m-%d %H:00') = DATE_FORMAT(date_sub(period_date, INTERVAL 7 DAY), '%Y-%m-%d %H:00')
) as o_wow
ORDER BY period_date DESC;
-- peak orders per minute --
SELECT period_date as peak_minute, order_count, gross_revenue, ROUND(gross_revenue / order_count, 2) AS gross_aov
FROM (
SELECT
COUNT(*) AS order_count,
ROUND(SUM(base_grand_total), 2) AS gross_revenue,
DATE_FORMAT(o.created_at, '%Y-%m-%d %H:%i') AS period_date
FROM sales_order o
WHERE o.created_at > '2000-01-01'
AND o.created_at <= CURDATE()
GROUP BY period_date
) t GROUP BY period_date
ORDER BY order_count DESC, period_date DESC LIMIT 10;
-- peak orders per hour --
SELECT period_date as peak_hour, order_count, gross_revenue, ROUND(gross_revenue / order_count, 2) AS gross_aov
FROM (
SELECT
COUNT(*) AS order_count,
ROUND(SUM(base_grand_total), 2) AS gross_revenue,
DATE_FORMAT(o.created_at, '%Y-%m-%d %H:00') AS period_date
FROM sales_order o
WHERE o.created_at > '2000-01-01'
AND o.created_at <= CURDATE()
GROUP BY period_date
) t GROUP BY period_date
ORDER BY order_count DESC, period_date DESC LIMIT 10;
-- peak orders per day --
SELECT period_date as peak_day, order_count, gross_revenue, ROUND(gross_revenue / order_count, 2) AS gross_aov
FROM (
SELECT
COUNT(*) AS order_count,
ROUND(SUM(base_grand_total), 2) AS gross_revenue,
DATE_FORMAT(o.created_at, '%Y-%m-%d') AS period_date
FROM sales_order o
WHERE o.created_at > '2000-01-01'
AND o.created_at <= CURDATE()
GROUP BY period_date
) t GROUP BY period_date
ORDER BY order_count DESC, period_date DESC LIMIT 10;
-- peak orders per week --
SELECT period_date as year_week, order_count, gross_revenue, ROUND(gross_revenue / order_count, 2) AS gross_aov
FROM (
SELECT
COUNT(*) AS order_count,
ROUND(SUM(base_grand_total), 2) AS gross_revenue,
DATE_FORMAT(o.created_at, '%Y-%u') AS period_date
FROM sales_order o
WHERE o.created_at > '2000-01-01'
AND o.created_at <= CURDATE()
GROUP BY period_date
) t GROUP BY period_date
ORDER BY order_count DESC, period_date DESC LIMIT 10;
-- avg orders per day of week past year--
SELECT period_date as day_of_week,
order_count,
ROUND(AVG(order_count), 1) AS avg_orders,
MAX(order_count) AS max_orders,
ROUND(AVG(gross_revenue), 2) AS avg_gross_revenue,
MAX(gross_revenue) AS max_gross_revenue,
ROUND(AVG(gross_revenue) / AVG(order_count), 2) AS avg_gross_aov
FROM (
SELECT
COUNT(*) AS order_count,
ROUND(SUM(base_grand_total), 2) AS gross_revenue,
DATE_FORMAT(o.created_at, '%W') AS period_date,
DATE_FORMAT(o.created_at, '%w') AS period_num
FROM sales_order o
WHERE o.created_at > date_sub(CURDATE(), INTERVAL 1 YEAR)
AND o.created_at <= CURDATE()
GROUP BY period_date, period_num
) t
GROUP BY period_date, period_num
ORDER BY period_num ASC;
-- avg and max orders per hourly period --
SELECT period_date as hour,
order_count,
ROUND(AVG(order_count), 1) AS avg_orders,
MAX(order_count) AS max_orders,
ROUND(AVG(gross_revenue), 2) AS avg_gross_revenue,
MAX(gross_revenue) AS max_gross_revenue,
ROUND(AVG(gross_revenue) / AVG(order_count), 2) AS avg_gross_aov
FROM (
SELECT
COUNT(*) AS order_count,
ROUND(SUM(base_grand_total), 2) AS gross_revenue,
DATE_FORMAT(o.created_at, '%Y-%m-%d %H:00') AS period_date
FROM sales_order o
WHERE o.created_at > date_sub(CURDATE(), INTERVAL 1 YEAR)
AND o.created_at <= CURDATE()
GROUP BY period_date
) t
GROUP BY period_date
ORDER BY period_date ASC;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment