MySQL - max summary by month - mysql

I have this entity:
payments(idPayment, idGroup, price, paymentDate)
and I would like to find out max month (recordable month). I have max price, but month is wrong.
Select Max(x.price), x.month, x.year from(
SELECT SUM(price) as price, Year(paymensDate) as year, Month(paymentDate) as month FROM `payments`
where idGroup=27 group by Year(paymentDate), Month(paymentDate)
) as x
Thanks for advices

You could use ORDER BY and LIMIT to pick the row with highest price amount
SELECT SUM(price) as price,
YEAR(paymensDate) as year,
MONTH(paymentDate) as month
FROM `payments`
WHERE idGroup=27
GROUP BY YEAR(paymentDate),
MONTH(paymentDate)
ORDER BY price DESC
LIMIT 1
MAX will give the max value for provided column but other values of column are not guaranteed to return the same values from that row which is picked by max

Related

Can I get every month of the year even if there is not data for that month in DB

I want to get a statistic for every month of the years i have in DB
SELECT monthname(created_at) AS month, YEAR(created_at) AS year, count(*) AS number
FROM tableName
WHERE type_of_user = "someType"
GROUP BY year, month(created_at)
ORDER BY created_at DESC
Now it gives me only month that I have, but I need to get statistics for every month, even if I don't have any stored data for that month
Create a calendar table. This will need one entry per month, for every year that you intend to use.
Then select from the calendar table, and join in the values that you get from your current query. Use COALESCE() to put a zero-value where the entry is NULL (e.g. when there are no records in the tableName for that month and year).
SELECT MONTHNAME(date) as month,
YEAR(date) as year,
COALESCE(number, 0) as number
FROM calendar AS C
LEFT JOIN (
SELECT created_at, COUNT(*) as number
FROM tableName AS T
WHERE T.type_of_user = 'someType'
GROUP BY YEAR(created_at), MONTH(created_at)
) AS T
ON MONTH(T.created_at) = MONTH(C.date) AND YEAR(T.created_at) = YEAR(C.date)
GROUP BY month, YEAR(created_at)
ORDER BY MONTH(date), YEAR(date)
SQL fiddle at http://sqlfiddle.com/#!9/e0a4dc/
SELECT month(created_at) as month
FROM tableName
RIGHT JOIN (select row_number() over (order by 1) as i
from someTableWithMoreThan12Records limit 12) x
ON x.i=month(created_at)
ORDER BY I;
JOINing with a table that has all the records will give you every month.

MySQL Finding the MAX of the SUM of each month of the year [MYSQL]

Currently i am able to get the sum for the highest amount for each month of the year. But what i want to do, is to be able to get the SUM of the month that has the highest value in amount for each year.
SELECT year(paymentDate), month(paymentDate) , SUM(amount)
FROM classicmodels.payments
GROUP BY year(paymentDate), month(paymentDate)
ORDER BY SUM(amount) DESC;
This orders the highest SUM(amount) in descending order but i only want to get the highest month for each year. there are only 3 years in my database.
Here's what happening on mysql workbench
One method uses a having clause:
SELECT year(p.paymentDate), month(p.paymentDate), SUM(p.amount)
FROM classicmodels.payments p
GROUP BY year(p.paymentDate), month(p.paymentDate)
HAVING SUM(p.amount) = (SELECT SUM(p2.amount)
FROM classicmodels.payments p2
WHERE year(p2.paymentDate) = year(p.paymentDate)
GROUP BY month(p2.paymentDate)
ORDER BY SUM(p2.amount) DESC
LIMIT 1
)
ORDER BY SUM(amount) DESC;

SQL, get the highest payment month of each year

I currently have this that shows me the total of how much the amount is per month. What i want to get from this, is to show the month that made the highest amount per each year.
SELECT year(paymentDate), month(paymentDate) , SUM(amount)
FROM classicmodels.payments
GROUP BY year(paymentDate), month(paymentDate)
ORDER BY paymentDate ASC;
Here is the table that i want to only show the month that got the highest amount for each year
You can use ROW_NUMBER for this:
SELECT y, m, amount
FROM (
SELECT YEAR(paymentDate) AS y, MONTH(paymentDate) AS m,
amount,
ROW_NUMBER() OVER (PARTITION BY YEAR(paymentDate) ORDER BY amount DESC) AS rn
FROM classicmodels.payments) AS t
WHERE t.rn = 1
Note: In case of ties the query return an arbitrary month. To return all months having the biggest amount use RANK instead of ROW_NUMBER.
Using ROW_NUMBER() you can assign sequence number for each records based on your criteria, and select the record with sequence 1.
Sample below;
SELECT *
FROM (
SELECT year(paymentDate) year_val, month(paymentDate) month_val, SUM(amount) amt_val,
ROW_NUMBER() OVER(PARTITION BY year(paymentDate) ORDER BY SUM(amount) DESC) AS ROW_ORDER
FROM classicmodels.payments
GROUP BY year(paymentDate), month(paymentDate)
) AS D
WHERE D.ROW_ORDER = 1
There are lot of other ways to achieve the same.
and WHERE D.ROW_ORDER = n --you will return the n'th highest for each year.
Give SUM(Amount) a column alias, ORDER BY <that alias> DESC and add TOP(1) to the SELECT

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;

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