MySQL - Display all amounts per month on a given fiscal year - mysql

I would to seek some help from the SQL Experts here in Stackoverflow.
I currently have this kind of table:
And I have been successfully getting the sum amount per year with this query:
select case when month(savings_date) >=11
then year(savings_date) +1
else year(savings_date)
end as fiscal, sum(amount)
from net_savings
group by fiscal
And having this output:
Now I would like to display all the sum amounts per month with a given input of fiscal year. How would I do this?
My fiscal year starts from november and ends at october. So if I have october 2015 in my records, it should not show up when I enter 2016 as fiscal year.

You can do this:
select month(savings_date), sum(amount)
from net_savings
where dateadd(savings_date, interval -2 month)
group by month(savings_date);

Related

Dynamic SQL query to select Quarters and perform aggregation on the data

sl.. Country Channel Type Clicks Spend Impressions Date
1. india Social a 14 $25 1,331 2/11/2021
2. india Search b 1,748 $1,801 1,166,140 2/11/2021
3. india Display c 28,615 $3,901 8,279,595 2/11/2021
4. india Display a 1,500 $1,000 1,233 7/10/2020
5. india Display a 11,500 $500 5,133 10/1/2020
6. india Display a 599 $200 6570 1/1/2020
So, what I needed to do is to create clicks/impressions for every quarter based on the historical data. The historical data is the same just that the dates are different, now to create (clicks/impressions) for this quarter the value will be
select sum(clicks)/sum(impressions)
from table_name
groupby (country, channel, type)
where ________
I need help in the where clause, I need to select the data from only some specific quarters while generating clicks/impressions for any quarter and the logic to select is:
Sum(clicks(q3 2020,q4 2020, q1 2020))/Sum(impressions(q3 2020,q4 2020, q1 2020))
where we need to find the quarters and the year from the date column.
By dynamically I mean if we move to the next quarter then I need to compare the average of the last 2 quarters and the same quarter previous year.
I wrote the code to find the quarters and year from the date, but how to proceed?
CASE
WHEN EXTRACT(MONTH FROM day) BETWEEN 7 AND 9 THEN 'Q1'
WHEN EXTRACT(MONTH FROM day) BETWEEN 10 AND 12 THEN 'Q2'
WHEN EXTRACT(MONTH FROM day) BETWEEN 1 AND 3 THEN 'Q3'
WHEN EXTRACT(MONTH FROM day) BETWEEN 4 AND 6 THEN 'Q4'
END AS quarter,
EXTRACT(Year FROM day) AS Year
Desired output
slno. quarter clicks/impressions
1. Q1 2021 0.53
2. Q4 2020 1.35
.......
When you're trying to filter data, don't do complex maths on the data and filter the results. That requires processing the whole table, then throwing away the rows not required.
Instead, do the maths in the filter parameters, which will allow the database to fulfil the filtering by checking indexes and only loading the rows it needs.
Fot example...
SELECT
SUM(clicks) / SUM(impressions)
FROM
yourTable
WHERE
(Date >= '2020-07-01' AND Date < '2021-01-01')
OR (Date >= '2020-01-01' AND Date < '2020-04-01')
That ensures you only process the data for the last two quarters of 2020, plus the first quarter of 2020.
The question then becomes, how to work out those dates based on today's date.
The start of the current quarter can be as provided by this... How do I get the first date of a quarter in MySQL?
If you store the result of that calculation in a variable named #CurrentQuarterStart, the WHERE clause becomes this...
WHERE
(Date >= #CurrentQuarterStart - INTERVAL 2 QUARTERS AND Date < #CurrentQuarterStart)
OR (Date >= #CurrentQuarterStart - INTERVAL 4 QUARTERS AND Date < #CurrentQuarterStart - INTERVAL 3 QUARTERS)

Select dates within the last week, but not only last 7 days

I want to select all dates within the last week.
But not by simply counting the current date - 7, as all posts Ive come across suggest.
This is how I actually have it for the SUM now....
SELECT SUM(total) FROM payforms WHERE user_id = 1 GROUP BY WEEK(date)
This gives me a nice total...
But I want to retrieve all individual records within the last week.
So I can use a BETWEEN query....but how do I get it to look in the current week.
Example...
Tuesday I want it to only find values from Sun, Mon, Tue.
On wednesday, I want it to find Sun, Mon, Tue, Wed.
On Saturday it finds the whole previous week. etc
So to be more clear....
I dont want it to find last Monday, on a monday.
On Mondays it should only display Mondays, if you get what I mean.
Can I do this??
Thanks
select * from payforms where yearweek(date) = yearweek(now());
Although I think MySQL weeks start on Sunday
You can make use of the WEEKDAY date function, which returns the day index of the week.
If I understand your question correctly, you could use this query:
SELECT date, SUM(total)
FROM payforms
WHERE date >= CURDATE() - INTERVAL DAYOFWEEK(CURDATE())-1 DAY
GROUP BY date
Please see fiddle here.
This will SUM all totals for every day of the current week, starting on last Sunday. If you want it to start on last Monday you can use this:
WHERE date >= CURDATE() - INTERVAL WEEKDAY(CURDATE()) DAY

how to get week average from month in mysql?

i have day, month, year, value columns in one table, here i need to get every week average value in one month.
how to get that. please help me regarding this.
select avg(value) from table group by month
gives month average.
select avg(value) from table group by day
gives day average.
but how to get week average from month field.
You can't "get weeks from a month" as one is not a subset of the other.
The number of days (and hence weeks) in 1 month varies from month to month and only in non-leap years - and in February only - are there exactly 4 weeks in a month.
You should use the original date field and use a date function to limit/group the data by week.
get the week in mySQL with
WEEK(timestamp)
or
YEARWEEK(timestamp)
or
WEEKOFYEAR(NOW())
or
DATE_FORMAT($yourDate, \'%X %V\') as week
There might be a better way, but my first thought is to write a query that calculates the week of the year for each day and groups them.
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_weekofyear
Something like:
SELECT avg(value) FROM table GROUP BY WEEKOFYEAR(CONCAT(year, '-', month, '-', day))

In MySQL date intervals, is 1 MONTH the same as 30 DAY? Is 1 QUARTER the same as 3 MONTH? And so on?

I am trying to write a PHP script that will process recurring payments every month, quarter, year, etc. This script will run as a nightly Cron job.
I don't want to run into a situation where somebody subscribes, say, on the 15th of a January, and then gets billed again on the 1st of February.
Is that what would happen if I checked the last payment against INTERVAL 1 MONTH? Or would it be the same as INTERVAL 30 DAY, and only process the payment again on the 15th of February, which is what I want?
Accroding to MYSQL
If you add MONTH, YEAR_MONTH, or YEAR and the resulting date has a day
that is larger than the maximum day for the new month, the day is
adjusted to the maximum days in the new month:
mysql> SELECT DATE_ADD('2009-01-30', INTERVAL 1 MONTH);
-> '2009-02-28' Date arithmetic operations require complete dates and do not work with incomplete dates such as '2006-07-00' or
badly malformed dates:
Thus if you use the 1 month built in function you do not have to worry when the last day of the month is. MYSQL does all the work for you.

SQL fiscal quarter totals... I've already got the calendar ones

Here's the SQL query I have for the calendar year's quarterly totals
SELECT
SUM(CASE WHEN WEEK(LAST_DAY) <= 13 THEN BILLABLE END) AS Q1
,SUM(CASE WHEN WEEK(LAST_DAY) >= 14 AND WEEK(LAST_DAY) <= 26 THEN BILLABLE END) AS Q2
,SUM(CASE WHEN WEEK(LAST_DAY) >= 27 AND WEEK(LAST_DAY) <= 39 THEN BILLABLE END) AS Q3
,SUM(CASE WHEN WEEK(LAST_DAY) >= 40 AND WEEK(LAST_DAY) <= 53 THEN BILLABLE END) AS Q4,
Emp_Name
FROM 'emp_info'
WHERE YEAR(LAST_DAY) = YEAR(CURRENT_TIMESTAMP)
GROUP BY Emp_Name
I need to shift it so it gives me the fiscal year (July 1 to June 30) totals.
I know when doing so the week numbers will need to start on July 1, not January 1 and there'll probably be a case statement in there somewhere. But I can't get it to come out correctly.
If I were you, I'd store fiscal quarters in a table. Then your queries would be dead simple. And not only would they be dead simple, it would be obvious when they were correct.
Try this query -
SELECT
Emp_Name,
IF(DATE(LAST_DAY) <= DATE('2011-6-30'), YEAR(LAST_DAY) - 1, YEAR(LAST_DAY)) f_year,
QUARTER(LAST_DAY) quarter,
SUM(BILLABLE)
FROM
emp_info
GROUP BY
Emp_Name,
f_year,
quarter;
You are aware that your query doesn't divide year into 4 quarters by month? Instead of using the WEEK() function use MONTH().
By operating on months and years (YEAR()) calculating sum for fiscal year will be easy.
Your real problem is going to be that generally speaking, date and time functions will only work on ISO/(Other common) calendar date/time objects, but you need them to work on a company-specific fiscal calendar.
This is why Calendar files are used, as a translation between fiscal and ISO calendars.
Generate your calendar fileout for a few years in either direction, then you can join to it, restricting/grouping by fiscal year and period. No case statements needed.
I also recommend storing most dates in your tables as actual ISO dates, then only translating/using fiscal dates when actually necessary - we have some summation tables here which are keyed off fiscal year/period, but which display shopping-behaviour data to customers (who don't know/care when our fiscal year is)...