Getting total sum of previous 3 month record - mysql

I need to get the total sum of the mark of previous 3 months. that is if I look on April I would get the sum of Jan, Feb, Mar. Similarly, When I look on Jan it displays the total of previous year Oct, Nov, Dec. I use the below query
SELECT empid,
name,
sum(total) AS total
FROM formresult
WHERE (MONTH(date) = MONTH(now())
OR MONTH(date) = MONTH(now()- INTERVAL 1 MONTH)
OR MONTH(date) = MONTH(now()- INTERVAL 2 MONTH))
AND YEAR(date) = YEAR(now())
GROUP BY empid
But when using this code I got 3-month result but when I look on Jan it does not display previous year result. How could it possible. Please Help me

Something like the following should do what you need.
SELECT empid, name, SUM(total) AS total
FROM formresult
WHERE date BETWEEN
DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 3 MONTH), '%Y-%m-01') AND
LAST_DAY(DATE_SUB(CURDATE(), INTERVAL 1 MONTH))
GROUP BY empid
See DATE_FORMAT(), DATE_SUB(), and LAST_DAY() for more information.

So there are a few issues with the date math that's being done here. First it looks like you are getting the current month and previous two months instead of the previous three months. This is getting you the current month MONTH(date) = MONTH(now()). Also you can't assume it's the current year, if you run this on January you'd expect to get October, November and December of the previous year however it will return for the current year.

Related

Mysql date_sub interval 12 month

I'm trying to get all posts from the 12 last month, group by month. I have a quite correct query:
SELECT MONTH(time) as mois, YEAR(time) as annee, count(*) as nbre
FROM touist_stories
WHERE time >= DATE_SUB(now() + INTERVAL 1 MONTH, INTERVAL 2 YEAR)
group by MONTH(time)
order by YEAR(time) DESC, MONTH(time) DESC
But one month is always missing : november 2012
I tryied to add
+ INTERVAL 1 MONTH
to now() but it still missing... How can I get the 12 last month and not the 11 ones please?
Thanks
To get one year ago, here's a technique I've used in the past. Using #mysql variables, create a date based on the first day of a given month/year (via now()), then subtract 12 months. This example will get from Oct 1, 2012 to current -- which will include current Oct 2013. To exclude that, just add to where clause where I re-added 1 year so it goes from Oct 1, 2012 at 12:00:00 am to LESS THEN Oct 1, 2013 12:00:00.
SELECT
MONTH(time) as mois,
YEAR(time) as annee,
count(*) as nbre
FROM
touist_stories,
( select #lastYear := date_add( DATE_FORMAT(NOW(),
'%Y-%m-01'), interval -11 month) ) sqlvar
WHERE
time >= #lastYear
group by
MONTH(time)
order by
YEAR(time) DESC,
MONTH(time) DESC
Revised to make it go 11 months back (to November per example), and include UP TO AND INCLUDING all Current October activity.
For realy want on year data use 11 MONTH not 12
SELECT time
FROM touist_stories
WHERE time
BETWEEN
date_sub(Now(), INTERVAL 11 MONTH)
AND
Now();

How to SELECT last calender month (not the interval)?

I have date time field called transaction_date, in a report i need to select last calendar month, how do i do this ? (this should work for a month like January too)
I came up with following but this only works if the month is NOT january,
SELECT SUM(amount) AS pay_month FROM `users_payment` WHERE MONTH(transaction_datetime)= MONTH(NOW()) AND YEAR(transaction_datetime)=YEAR(NOW())
there are lot of examples using INTERVAL functions but this only select the time interval not the calendar month as i wanted too..
like
SELECT SUM(amount) AS `year_month` FROM `users_payment` WHERE DATE_ADD(NOW(), INTERVAL -1 MONTH) < transaction_datetime
but this is not what i want, i want to select sales sum of the DECEMBER only last year (remember there are other years too in the table which i dont want i.e 1979, 1981...etc)
same report next section, i need to select last 2 calender months, I dont know have any idea on how to do this too.
Have you tried the following
SELECT SUM(amount) AS `year_month` FROM `users_payment`
WHERE MONTH(DATE_ADD(NOW(), INTERVAL -1 MONTH)) = MONTH(transaction_datetime)
The above should work to show previous month; it does not distinguish between years however.
On second thought, I see what you are trying to do - To get all the transactions for a given month. Try something like this instead.
SELECT SUM(amount) AS `year_month` FROM `users_payment`
WHERE transaction_datetime BETWEEN date_format(NOW() - INTERVAL 1 MONTH, '%Y-%m-01')
AND last_day(NOW() - INTERVAL 1 MONTH)
This will list all the transactions for the previous calendar month. Alter the INTERVAL values to select multiple months.
You can try this--
SELECT SUM(amount) AS pay_month FROM `users_payment` WHERE
PERIOD_ADD(DATE_FORMAT(NOW(),'%Y%m'), -1) = DATE_FORMAT(transaction_datetime,'%Y%m')

MySQL: Select values based on current month and day

I have a MySQL table called history that includes a column called month: January, February, March, etc. and a column called day_num containing day numbers from 1 to 31.
I need to be able to select a month and a day from the two corresponding columns, based on the current month and day.
I know it's a rather embarrasingly basic question, but - how do I do that?
SELECT month, day_num FROM history WHERE ??????? ORDER BY RAND() LIMIT 1;
Would appreciate a bit of advice from a knowledgeable person.
SELECT *
FROM History
WHERE DATE_FORMAT(CURDATE(), '%M') = `month` AND
DAY(CURDATE()) = `day_num`
SQLFiddle Demo
OR
SELECT *
FROM History
WHERE MONTHNAME(CURDATE()) = `month` AND
DAY(CURDATE()) = `day_num`
SQLFiddle Demo
Other Sources
MONTHNAME
DAY

MySQL - order by one month from today

How to order records by one month from today. I have tried the following but it does not work.
WHERE MONTH(date) = MONTH(CURDATE() -1 month)
Do you mean this? This will get you everything in your table where the month of the date field is equal to the current month - 1:
WHERE MONTH(date) = month(curdate() - interval 1 month)
WHERE MONTH(date) = MONTH(CURDATE() - INTERVAL 1 MONTH)
Hard to tell what you're after from your question, so I'm taking a punt that you want to show records that have the date that is exactly one month from now
SELECT *
FROM yourtable
WHERE MONTH(date) = MONTH(DATE_SUB(CURDATE(), INTERVAL 1 MONTH))
That will get all entries for October, if we are currently in November.
If you want it down to the day, so if today is November 20 you want to grab items from October 20, you'll need something like this
SELECT *
FROM agentjobsets
WHERE DATE(created_at) = DATE_SUB(CURDATE(), INTERVAL 1 MONTH)

Upcoming birthdays year bug (SQL)

this is my current sql query that gets all the upcoming birthdays for my company in the next 90 days:
SELECT
user.birthday, user.name, MONTH(user.birthday)
AS month, DAY(user.birthday) AS day
FROM user WHERE
(1 =
(FLOOR(DATEDIFF(DATE_ADD(DATE(NOW()),INTERVAL
90 DAY),birthday) / 365.25)) -
(FLOOR(DATEDIFF(DATE(NOW()),birthday)
/ 365.25)))
ORDER BY MONTH(birthday),DAY(birthday)
The problem, is that if right now is november, and there are some birthdays in january, it will display january birthdays first, then november and then december, although january birthdays already happened THIS year.
Is there a way to reorder this records in the same SQL query, so that it displays current and future months first, and THEN next year's months?
First partial solution thanks to Johan
ORDER BY ( MONTH(birthday) > MONTH(NOW()
OR ((MONTH(birthday) = MONTH(now())
AND DAY(birthday) >= DAY(NOW()) DESC
, MONTH(birthday), DAY(birthday)
Still it needs a little improvement. If a birthday already happened, it should be displayed AFTER december on the results. Example of what should be displayed assuming it is 27th june
28 june: john doe
27 december: mary wright
5 june (next year of course): mad max
I'm not sure but it seems that your birthday includes the year. If that's so than you'll have a range of birthdays per user (one for every year) and you can just select the ones within the next 90 days.
SELECT
user.birthday
, user.name
, MONTH(user.birthday) AS month
, DAY(user.birthday) AS day
FROM user
WHERE birthday BETWEEN NOW() AND DATE_ADD(NOW, INTERVAL 90 DAY)
ORDER BY Birthday DESC
If your birthday only has a month and day, your query needs to be:
SELECT
user.birthday
, user.name
, MONTH(user.birthday) AS month
, DAY(user.birthday) AS day
FROM user
WHERE STR_TO_DATE(CONCAT(YEAR(NOW()),MONTH(birthday),DAY(birthday)),'%YYYY%M%D')
BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 90 DAY) OR
STR_TO_DATE(CONCAT(YEAR(DATE_ADD(NOW(),INTERVAL 1 YEAR)),MONTH(birthday),DAY(birthday)),'%YYYY%M%D')
BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 90 DAY)
ORDER BY ( MONTH(birthday) > MONTH(NOW()
OR ((MONTH(birthday) = MONTH(now()) AND DAY(birthday) >= DAY(NOW()) DESC,
MONTH(birthday), DAY(birthday)
I believe you need to order using something that includes the year.
ORDER by date_format( date, "%d/%m/%Y" )
I am no expert but something like this may work too.
ORDER BY YEAR(birthday),MONTH(birthday),DAY(birthday)
I think you want to know if each user's birthday, brought in to the current year or the next year, falls between your range:
SELECT name, birthday
FROM (SELECT name, birthday, YEAR(NOW()) - YEAR(birthday) AS years_ago
FROM user) d
WHERE DATE_ADD(birthday, INTERVAL years_ago YEAR)
BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 90 DAY)
OR
DATE_ADD(birthday, INTERVAL (years_ago + 1) YEAR)
BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 90 DAY);
(It occurs to me that you might actually want INTERVAL 3 MONTH, rather than 90 DAY, expecially if you intend to run this query on the first of every month.)
Your query will create a full table scan.
Store an integer containing the day of the year (1st of april is going to be around 90), and compare that with the current day of the year.
I've been searching for this code, but I couldn't find a clean/simple query (that also works with leap-years (29th of february problem))
So i've made my own.
Here's the simplest code to get the upcoming birthdays for the next x days, (this query also displays the birthdays of yesterday (or you can change it to a x number of days in the past)
SELECT name, date_of_birty
FROM users
WHERE DATE(CONCAT(YEAR(CURDATE()), RIGHT(date_of_birty, 6)))
BETWEEN
DATE_SUB(CURDATE(), INTERVAL 1 DAY)
AND
DATE_ADD(CURDATE(), INTERVAL 5 DAY)