MySQL not returning each year - mysql

I'm trying to have this query show the empid and ordercount from each year. The only year being returned is 2006. The order table itself has a lot of orders ranging from 2006-2008.
select empid, year(orderdate) as orderyear, count(empid) as ordercount
from orders
group by empid
order by year(orderdate);

If you want the order count for each empid and each year, you need to group by the year too:
SELECT empid, YEAR(orderdate) AS orderyear, COUNT(empid) AS ordercount
FROM orders
GROUP BY empid, YEAR(orderdate)
ORDER BY YEAR(orderdate);

Related

Mysql query for getting monthwise n th highest spending customer

I am using sakila.payment table.
Columns: payment_id, customer_id, staff_id, rental_id, amount, payment_date, update_date
I am using this query to get customers spending the highest amount for each month.
How can I get the Nth highest spending customer for each month?
select customer_id,`month`,max(total_amount) from
(SELECT customer_id,count(customer_id) as `count`,month(payment_date) as `month`,sum(amount) as total_amount
FROM sakila.payment
group by month(payment_date),customer_id
order by `month` asc, `total_amount` desc)t
group by `month`
Try the following, if you are using MySQL 8.0 then it will work with row_number()
select
customer_id,
month,
total_amount
from
(
select
customer_id,
month,
total_amount,
row_number() over (partition by month order by total_amount desc) as rnk
from
(
select
customer_id,
count(customer_id) as `count`,
month(payment_date) as `month`,
sum(amount) as total_amount,
from sakila.payment
group by
month(payment_date),
customer_id
) cal
) mnt
where rnk = 1

MySQL Select Top Row Grouping By Another Row

I have a sales table and I want to get each members most frequently shopped store in the last 3 months. The following query will get the every member with every store, but I want just one store per member.
SELECT member_id, store_id, COUNT(DISTINCT docket) as docket_count, SUM(dollar_amount) as dollars
FROM sales
WHERE TIMESTAMPDIFF(MONTH, sale_date, CURDATE()) < 3
GROUP BY member_id, store_id
ORDER BY member_id, docket_count DESC, dollars DESC
Or to get the top store for a single member
SELECT store_id, COUNT(DISTINCT docket) as docket_count, SUM(dollar_amount) as dollars
FROM sales
WHERE TIMESTAMPDIFF(MONTH, sale_date, CURDATE()) < 3
AND member_id = 1
GROUP BY store_id
ORDER BY docket_count DESC, dollars DESC
This is tricky. In MySQL, this can be easiest using the group_concat()/substring_index() trick:
SELECT member_id,
SUBSTRING_INDEX(GROUP_CONCAT(store_id ORDER BY docket_count DESC dollars DESC), ',', 1) as Most_Common_Store
FROM (SELECT member_id, store_id, COUNT(DISTINCT docket) as docket_count,
SUM(dollar_amount) as dollars
FROM sales
WHERE sale_date >= CURDATE() - interval 3 month
GROUP BY member_id, store_id
) ms
GROUP BY member_id;

How can i get count of customers per day by unique and repeat customer for specific date?

I am trying to get a result from my order table to get list of counts of customers who 1st time ordered and repeat orders. Something like below.
Date 1st time time repeat order
2014-09-01 43 90
2014-09-02 3 45
2014-09-03 12 30
2014-09-04 32 0
2014-09-05 1 98
I am beginner in sql and i ma using mysql.
My table structure is like.
OrderNumber int
OrderDate datetime
CustomerID int
I have tried this query in mysql but it only gives me first timed ordered count.
SELECT DATE(OrderDate), COUNT(*)
FROM orders T JOIN (
SELECT MIN(OrderDate) as minDate, CustomerID
FROM orders
GROUP BY CustomerID) T2 ON T.OrderDate = T2.minDate AnD T.CustomerID = T2.CustomerID
GROUP BY DATE(T.OrderDate)
You can get the total orders per day by grouping on OrderDate:
SELECT OrderDate, COUNT(OrderNumber) AS total FROM orders GROUP BY OrderDate
And you can get the no. of first orders per day from the following query :
SELECT OrderDate, COUNT(q1.CustomerID) AS first FROM (SELECT CustomerID, min(OrderDate) AS OrderDate FROM orders GROUP BY CustomerID)q1 GROUP BY q1.OrderDate
Now join these two on OrderDate to get the distribution of first and repeated orders :
SELECT a.OrderDate, a.first, (b.total - a.first) AS repeated FROM
(SELECT OrderDate, COUNT(q1.CustomerID) AS first FROM (SELECT CustomerID, min(OrderDate) AS OrderDate FROM orders GROUP BY CustomerID)q1 GROUP BY q1.OrderDate)a
JOIN
(SELECT OrderDate, COUNT(OrderNumber) AS total FROM orders GROUP BY OrderDate)b
on(a.OrderDate = b.OrderDate)
A slightly complicated query but this should do:
First Time Users: Just Group by customerID to get the min orderdate and then group by on that date to get the number of new users on a particular day. Query would look like this:
select date(mdate) as day, COUNT(*) from (select customerid, min(orderdate) as mDate from orders GROUP BY CustomerID)q1 GROUP BY day;
Repeat Users: First filter out all such orderno which were placed as first orders and then do a group by orderdate to get repeat. Query would be :
select date(orderdate) day, COUNT(*) from (select * from orders where orderno not in (select orders.orderno from orders JOIN (select customerid, min(orderdate) as mdate from orders GROUP BY CustomerID)as order2 ON (orders.customerid = order2.customerid) and (orders.orderdate = order2.mdate))) as q1 GROUP BY day;
You can do a join on day for both these queries to get combined results in a way you mentioned. Let me know if doesn't work
EDIT:
This would be the complete query: Here I am doing a UNION on both left and right outer joins since it might happen that you come across where there are no new requests or no repeated requests. This would take care of both the scenarios.
select q2.*, q3.repeated from (select date(mdate) as day, COUNT(*) as first from (select customerid, min(orderdate) as mDate from orders GROUP BY CustomerID)q1 GROUP BY day) as q2 LEFT OUTER JOIN (select date(orderdate) day, COUNT(*) as repeated from (select * from orders where orderno not in (select orders.orderno from orders JOIN (select customerid, min(orderdate) as mdate from orders GROUP BY CustomerID)as order2 ON (orders.customerid = order2.customerid) and (orders.orderdate = order2.mdate))) as q1 GROUP BY day) as q3 on q2.day = q3.day UNION select q2.*, q3.repeated from (select date(mdate) as day, COUNT(*) as first from (select customerid, min(orderdate) as mDate from orders GROUP BY CustomerID)q1 GROUP BY day) as q2 RIGHT OUTER JOIN (select date(orderdate) day, COUNT(*) as repeated from (select * from orders where orderno not in (select orders.orderno from orders JOIN (select customerid, min(orderdate) as mdate from orders GROUP BY CustomerID)as order2 ON (orders.customerid = order2.customerid) and (orders.orderdate = order2.mdate))) as q1 GROUP BY day) as q3 on q2.day = q3.day
this is my answer but not sure is still can improve.
SELECT userID, COUNT(*) AS repeat_order_cnt FROM
(SELECT DATE(OrderDate) AS order_DT, userID, COUNT(*) AS no_of_order FROM order
AND YEAR(orderDate) = '2015'
AND MONTH(orderDate) = '01'
GROUP BY order_DT,userID) AS order2
GROUP BY userID
HAVING COUNT(*) > 1

Select average monthly count, grouped by a field

I'm not sure if this has been asked before, as I don't know how to best phrase this question.
Given a query like:
SELECT DATE_FORMAT(i.created, '%Y-%m') as 'period',
COUNT(id) as 'total',
i.company_id
FROM invoice i
GROUP BY period, i.company_id
ORDER BY period DESC, total DESC
How can I return the average and/or mean count per month, grouped by company_id? It is important to only count those periods where there actually are any invoices.
If you want to exclude zero months then add HAVING condition and then select AVG() for each company using your query as a base:
SELECT company_id, AVG(total)
FROM
(SELECT DATE_FORMAT(i.created, '%Y-%m') as 'period',
COUNT(id) as 'total',
i.company_id
FROM invoice i
GROUP BY period, i.company_id
HAVING COUNT(id)>0
) as T1
GROUP BY company_id

MYSQL inline view query (top customer)

I try to make a query, so that I can see who is the top customer in a month (every month since begin till now).
Now I have the tables:
orders (orderID, orderdate, customerID, Netamount, tax, totalamount)
orderline (orderlineID, orderID, prodID, quantity, orderdate)
customer (firstname lastname zip creditcardtype etc.)
I think the other tables aren't necessarily here.
Of course there are customers who never bought a thing and customers who already bought plenty of times.
Now I used this query:
SELECT customerid, Sum(netamount)
FROM orders
GROUP BY customerid limit 1000000;
Now I see all customers who already bought sth. with the total amount they paid.
With the query
SELECT YEAR ( Orderdate ) Year ,
MONTHNAME ( Orderdate ) Month ,
COUNT(*) TotOrd ,
FROM orders
GROUP BY YEAR ( Orderdate ),
MONTH ( Orderdate );
I get a table where each row shows me the Year Month Total order (placed in that month).
Still I want just to see the Top Customer of a month.
I searched a lot in the internet still couldn't find that what I want (maybe I just googled wrong). I know that I need at least one inline view still no idea how to realize it.
Hope someone can help me out here.
You need to join back to the data to get the top customer. So, first calculate the maximum amount in each month, then join back to get the customer with that amount:
select my.year, my.month, myc.customerid, myc.totord
from (select year, month, max(totord) as maxtotord
from (SELECT YEAR ( Orderdate ) Year, MONTHNAME ( Orderdate ) Month, customerid, COUNT(*) TotOrd ,
FROM orders
GROUP BY YEAR ( Orderdate ), MONTH ( Orderdate ), customerid
) myc
group by year, month
) my join
(SELECT YEAR ( Orderdate ) Year, MONTHNAME ( Orderdate ) Month, customerid, COUNT(*) TotOrd ,
FROM orders
GROUP BY YEAR ( Orderdate ), MONTH ( Orderdate ), customerid, count(*) as totord
) myc
on my.year = myc.year and my.month = myc.month and my.maxtotord = myc.totord
Note that this is untested, so there might be a syntax error.
Also, this returns multiple customers if there are multiple customers with the max value.
Finally, this is much easier in almost any other database, because most databases now support the row_number() function.
It's a group-wise max problem but unfortunately MySQL doesn't support window functions or CTE so this can be messy.
SELECT s1.year,s1.month,s1.customerid,s1.totord FROM
(SELECT YEAR ( Orderdate ) Year ,
MONTHNAME ( Orderdate ) Month ,
customerid,
COUNT(*) TotOrd
FROM orders
GROUP BY YEAR ( Orderdate ),
MONTH ( Orderdate ),customerid) as s1
LEFT JOIN
(SELECT YEAR ( Orderdate ) Year ,
MONTHNAME ( Orderdate ) Month ,
customerid,
COUNT(*) TotOrd
FROM orders
GROUP BY YEAR ( Orderdate ),
MONTH ( Orderdate ),customerid) as s2
ON
s1.year=s2.year AND s1.month=s2.month AND s2.TorOrd>s1.TotOrd AND s1.customerid>s2.customerid
WHERE s2.customerid IS NULL;
In case of doubles it will return the customer with lower id.