Need a query to find consecutive orders by month
-
06-07-2021 - |
سؤال
I am having trouble writing this query.
I need to get the current number of orders that were shipped in consecutive months.
Example: if the current month is November and they placed orders in July, August, September, October, November, it would return 5 for that user. If they didn't place an order in November, it would return 0 because their streak is broken.
The tables I'm concerned with are customer
, order
, and date
.
المحلول
Use a cross join between the date table and the customer table to get a row for every customer / month combination and then left join that against the order table to get the details, using group by to get the counts.
Something like this, although you will need to modify it to cope with the column names being reserved words.
SELECT customer.name, month.name, COUNT(order.id)
FROM customer
CROSS JOIN date
LEFT OUTER JOIN order
ON customer.id = order.customer_id
AND MONTH(date.date) = MONTH(order.date)
WHERE date.date BETWEEN startofdaterange AND endofdaterange
GROUP BY customer.name, month.name
Or if I have misread the question, and you need a count of the orders if they order every month in the range, or 0 if they skipped a month then something like this (not tested so expect a typo or 2, would need the table def to test):-
SELECT name, CASE WHEN MonthCount = MonthOrderCount THEN OrderCount ELSE 0 END AS ContinuousOrderMonths
FROM (
SELECT CustName, COUNT(MonthName) AS MonthCount, SUM(MonthOrderCount) AS OrderCount, SUM(CASE WHEN MonthOrderCount > 0 THEN 1 ELSE 0 END)
FROM (
SELECT customer.name AS CustName, month.name AS MonthName, COUNT(order.id) AS MonthOrderCount
FROM customer
CROSS JOIN date
LEFT OUTER JOIN order
ON customer.id = order.customer_id
AND MONTH(date.date) = MONTH(order.date)
WHERE date.date BETWEEN startofdaterange AND endofdaterange
GROUP BY customer.name, month.name )Sub1 ) Sub2
GROUP BY CustName
If you want a list of customers and a comma separated list of orders per month:-
SELECT CustName, GROUP_CONCAT(CAST(MonthsOrder AS CHAR))
FROM (
SELECT customer.name AS CustName, month.name, COUNT(order.id) AS MonthsOrder
FROM customer
CROSS JOIN date
LEFT OUTER JOIN order
ON customer.id = order.customer_id
AND MONTH(date.date) = MONTH(order.date)
WHERE date.date BETWEEN startofdaterange AND endofdaterange
GROUP BY customer.name, month.name) Sub1
GROUP BY CustName
You might have to expand this to get the month name with each one and force the order
نصائح أخرى
Here you replace now and static date as per columnname :
select (case
when (month(now())=11 and
(month('2012-02-02')>=7 and month('2012-02-02')<=11))
then 5
else
0 end) as 'month'
from tablename