MySql get rows from last months same day - mysql

I want to get records from last month's same day by keeping in mind for days which will be skipped and should be included in next day.
e.g. on 31st of march, february 31 does not exist so it should skip the query and also if i want to get records on april 30 it will give the results as required, but then on 1st of may, 31st of march will be skipped.
Currently, I am using
SELECT * FROM registrations WHERE orderdate = DATE_SUB(CURDATE(), INTERVAL 1 month)
How can I tackle this in mysql query?
Sorry if i am not able to communicate my query.

Consider the following logic, which retains a record only if subtracting one month did not result in an earlier day value:
SELECT *
FROM registrations
WHERE
orderdate = DATE_SUB(CURDATE(), INTERVAL 1 month) AND
DAY(orderdate) = DAY(DATE_SUB(CURDATE(), INTERVAL 1 month));

Related

Why did MySQL SUM IF quit working in 2021

This code quit working in 2021 after working in 2020:
SELECT name, SUM(CASE WHEN YEARWEEK(prod_date) = YEARWEEK(now()- INTERVAL 1 WEEK) THEN gas_prod ELSE NULL END) AS LastWeek FROM daily_prod GROUP BY name
The code now calculates a larger number than occurred last week. Any reason why a new year would cause this code to work differently?
First, using the sum( case/when ) is a bad choice here. Your query is going against your ENTIRE daily_prod table, EVERY RECORD, but only summing when within the given yeardate() period based on whatever the current date is. Instead of doing that, build out a WHERE clause to just get the records you care about. The YearWeek() function is based on a Sunday to Saturday week schedule. So, for example this week is from Jan 31 at 12:00am (midnight) up to, but not including Feb 7th at 12:00am midnight. This includes everything up to Feb 6th at 11:59:59pm.
So, by doing embedded MySQL variables you can build as a "from" table alias as I will show. First, lets get whatever the current NOW() is which is inclusive of hour/minute/second and strip down to just the date portion. Ex: 2021-02-04 # 01:42am truncates down to just 2021-02-04 12:00am
select cast( now() as date )
From that, now, we need to go to the first of the week, represented as Sunday. For this, we use the day of the week and subtract 1 so it is a zero-based value where Sunday = 0, Saturday = 6. So Thursday, normally returns 5, subtract 1 = 4. February 4 - 4 days = Jan 31 which is the first of the current week.
select date_sub( [result of sql above], interval dayofweek( [result of sql above] ) -1 day )
Now, since you want the entire week of data, in this scenario, your data would be from Jan 31 at 12:00am in the morning up to Feb 6th (Saturday) at 11:59:59PM. So, take the above beginning of the week and add 1 week to it bringing you to Feb 7th.
select date_add( [result of 2nd query], interval 1 week )
Yes, this is intentional because now in your final query you can query LESS THAN Feb 7th.
So, by using a where on your data source, you only get those records, AND, if your table has an index on the transaction date, can be optimized for the query. To use inline variables, we can just use the results of these as part of the query such as:
SELECT
dp.name,
SUM( dp.gas_prod ) CurrwntWeekGas
FROM
daily_prod dp,
( select
-- first, variable #nd = Now as a date only
#nd := cast( now() as date ),
-- from the #nd, subtract 0-based day of week
-- example: Thursday is 5th day of week -1 = 4 days to subtract
#fow := date_sub( #nd, interval dayofweek( #nd ) -1 day ),
-- finally from the first of the week, add 1 week to the END point for the query
#nextWeek := date_add( #fow, interval 1 week )
) sqlvars
where
-- only grab records greater or equal to the first day of the week
dp.prod_date >= #fow
-- and ALSO LESS then the the beginning of NEXT week
AND dp.prod_date < #nextWeek
GROUP BY
dp.name
So, as the from clause alias "sqlvars" is processed, it creates the 3 "#" variables to define the beginning of week and beginning of NEXT week values. Those can then be applied to the where clause and limit just the records you need, not the full table.
If you really want the results of the prior week from the week you are in... Ex: the total from Jan 24th to Jan 30th since the current week has not completed, then just change your dayofweek() -1 to dayofweek() -8 to get the entire prior week, not the CURRENT week you are in the middle of now.

Return all records within 3 month period (MySQL)

So what I want to achieve is to return data from within the last 3 months.
My current MySQL query is as follows:
SELECT MONTH(service_date_time) AS month, SUM(service_price) AS total FROM appointments WHERE user_id = 1 AND service_date_time >= last_day(now()) + INTERVAL 1 day - INTERVAL 3 month GROUP BY YEAR(service_date_time), MONTH(service_date_time)
My table appointments contains data from January and May and service_date_time is a date_time field.
The problem I'm having is that it returns 2 rows, one row totaling the price for January and one row totaling the price for May. The row for May shouldn't be returned since it is not within the past three months.
Anyone have an idea why?
You are requesting all records that are greater than the given date, If you want all the records up to now you'll have to ask for a range for example:
WHERE service_date_time BETWEEN (LAST_DAY(NOW()) + INTERVAL 1 DAY - INTERVAL 3 MONTH) AND NOW()
this would limit the records & give you from 3 months ago till now

select all data beginning from the first of the month sql

I'm trying to get data going back three months for monthly reports. I got to the point where i can get all the data. The problem is that it goes back 3 months based on the current date.
Example: If today is 7th of November it will give me the data up until the 7th of August.
I need it to give me the data going back three months but starting from the first of the month.
Example: today is the 7th of November, I'll need the data starting from the 1st of August.
Here is the code I'm using to get the data from three months back:
SELECT * FROM 'closed_wo_journal' WHERE date_time_stamp > CURDATE() - INTERVAL 3 MONTH
The date_trunc function is just what the doctor ordered:
SELECT *
FROM closed_wo_journal
WHERE date_time_stamp > DATE_TRUNC('MONTH', CURDATE() - INTERVAL '3 MONTH')
Here is logic to get the first of the month, three months ago:
SELECT j.*
FROM closed_wo_journal j
WHERE j.date_time_stamp >= ( CURDATE() - INTERVAL (1 - DAY(CURDATE()) DAY) ) - INTERVAL 3 MONTH )

Getting the last month's dates in mysql

I need to get the last month's dates from 1st to current date. Suppose if today's date is March 25th, I need to get the dates from 1st to 25th of february. Suppose if today's date is March 30th, I need to get the dates from 1st to 28/29th Feb, whatever the maximum final date is available. I have searched a lot to get that, but no luck. Can someone please help me how to get this special case done? I am able to do it on another database, but I want to do this on mysql.
Basically what I did for other database is this --> date between date(to_char(date(add_months(DATE(sysdate) ,-1)),'YYYY-MM-01 00:00:00')) and date(add_months(DATE(sysdate) ,-1))
This should do what you want:
WHERE d BETWEEN DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), '%Y-%m-01')
AND DATE_SUB(CURDATE(), INTERVAL 1 MONTH);
You can use DATE(DATE_SUB(NOW(), INTERVAL 1 MONTH)). This will automatically limit the result to the last day of the month, so if today's date is March 30th, this will return Feb 28th.

Get data up until last day of previous month in MySQL

I've got an mysql-db with charges in it, with a datetime. Every month i want to create an invoice with all the charges from last month or earlier. So if it´s may 2nd, 5th or 30th 2012, i still only want the invoices from april 2012 or earlier. I've tried with date_sub, but it just subtracts a month, so it only invoices up to the same day of the previous month. How should i do this?
get * from Ads WHERE AdEnd > ??
Ty!
I always found that if you subtract the day of the month in days from the current date, you'll get the last day of the previous month. For example, on the 15th of the month, subtract 15 days, and you'll end up with the last day of the previous month:
SELECT (DATE_SUB(CURDATE(),INTERVAL DAYOFMONTH(CURDATE()) DAY))
If CURDATE() is 2012-05-05 then the above returns 2012-04-30.
So, to get Ads up to the last day of last month, do something like this:
SELECT *
FROM Ads
WHERE AdEnd <= (DATE_SUB(CURDATE(),INTERVAL DAYOFMONTH(CURDATE()) DAY))
This works if AdEnd is a DATE, but if it's a DATETIME, you'll just want to do less than the first of the month, so you subtract one less day to get the first of the month like this:
SELECT *
FROM Ads
WHERE AdEnd < (DATE_SUB(CURDATE(),INTERVAL DAYOFMONTH(CURDATE()) - 1 DAY))
Try date_diff, for example:
SELECT DATEDIFF('2008-11-30','2008-11-29') AS DiffDate
yields:
1