MYSQL one day interval from 00:00:00 to 23:59:00 - mysql

I am trying to pickup 1 day previous records based on few dates and time stamps but my is not retrieving recorders from 00:00:00 to 23:59:00. I am using the follwoing criteria.
and ((cast(from_unixtime(schedule.last_change_timestamp) as date) = (curdate() - interval 1 day))
or (cast(schedule.date_added as date) = (curdate() - interval 1 day))
or (left(jobsheet.actual_completion_date_set, 10) = (curdate() - interval 1 day))
or (cast(from_unixtime(orders.dateadded) as date) = (curdate() - interval 1 day)))),
The records which I am missing are most likely related to jobsheet.actual_completion_date_set which is in this format
'yyyy-mm-dd hh:mm:ss' and I am using left 10 characters for interval. Please could someone provide some help as to how I can force all these dates to select all records from 00:00:00 to 23:59:00 the previous day.
Thanks,

Is this what you want?
left(jobsheet.actual_completion_date_set, 10) = date_format(date_sub(curdate(), interval 1 day, '%Y-%m-%d')
In MySQL, I find it safer to use date_sub() and date_add() for the built-in constants. These are not returned as datetime or date, so strange things can happen with conversions to the dates.

Related

Problem in getting records from last 13 months in MySQL

I am working on to get records from last 13 months using following MySQL query:
SELECT YEAR(`customer_date`),
MONTHNAME(`customer_date`),
COUNT(`customer_date`) AS Enquiries
FROM `crm_customers`
WHERE DATE(`customer_date`) BETWEEN CURRENT_DATE - INTERVAL 13 month AND
CURRENT_DATE
GROUP BY YEAR(`customer_date`),
MONTH(`customer_date`)
ORDER BY YEAR(`customer_date`) DESC,
MONTH(`customer_date`) DESC
My prototype MySQL table crm_customers looks as:
customer_id customer_date
1 2019-02-01 00:00:00
2 2019-02-02 00:00:00
... ...
... ...
... ...
Output:
Though above query does work fine and gives me almost correct result set except one issue related to very last month of the last year from a gap of 13 months from today.
Today is 7th of March 2020. The date condition in my above query
WHERE DATE(`customer_date`) BETWEEN CURRENT_DATE - INTERVAL 13 month AND CURRENT_DATE
starts fetching the result from 7th of Feb 2019.
In the month of Feb, 2019 I have 104 entries. But my above SQL fetches only 80 entries because 24 entries are before 07-Feb-2019 (between 1 Feb and 6 Feb 2019). I want to include those entries as well. How can I modify my date condition to achieve the required result.
EDIT
Why this question is marked negative? I don't understand. Question is very much clear and not duplicated. Is it down voted by GMB?
change your WHERE clause to:
WHERE DATE(`customer_date`) BETWEEN DATE_FORMAT(NOW() ,'%Y-%m-01') - INTERVAL 13 month AND DATE_FORMAT(NOW() ,'%Y-%m-01')
There are some possibility to achieve this
SELECT CURDATE()
, CAST(DATE_FORMAT(NOW() ,'%Y-%m-01') as DATE)
,LAST_DAY(NOW() - INTERVAL 1 MONTH) + INTERVAL 1 DAY;
Results in
CURDATE() , CAST(DATE_FORMAT(NOW() ,'%Y-%m-01') as DATE), LAST_DAY(NOW() - INTERVAL 1 MONTH) + INTERVAL 1 DAY
2020-03-07, 2020-03-01 , 2020-03-01
Sounds like you want to reduce precision in your DATE value. Use EXTRACT() for this;
EXTRACT(YEAR_MONTH FROM CURDATE() - INTERVAL 13 MONTH)
I would suggest:
where
customer_date >= date_format(current_date, '%Y-%m-01') - interval 13 month
and customer_date < current_date + interval 1 day
Rationale:
this compares the stored date without prior transformation (while your query, and all answers so far, use date()), which makes it possible to benefit an existing index - on a large dataset, this can make a big performance difference
date arithmetics is as simple as possible; MySQL happily treats strings in proper formats as dates, which can shorten the syntax

Better way to write a difference based date queries

I'm doing a review of existing code and have found the following SQL query which is used to get a selection of records last month.
Is there a more concise way of writing SQL to do what this date based clause does in MySQL?
SELECT foo
FROM some_table
WHERE some_date
BETWEEN
DATE_FORMAT(LAST_DAY((NOW() - INTERVAL 1 MONTH) - INTERVAL 1 SECOND), '%Y-%m-01 00:00:00')
AND
DATE_FORMAT(LAST_DAY((NOW() - INTERVAL 1 MONTH) - INTERVAL 1 SECOND), '%Y-%m-%d 23:59:59')
It works, but I just twitch a little every time I see it.
Can anyone else write it better?
Thank you in advance.
There's no need to format the dates, they default to YYYY-MM-DD 00:00:00.
This is a little bit simpler:
SELECT foo
FROM some_table
WHERE some_date >= LAST_DAY(CURDATE() - INTERVAL 2 MONTH) + INTERVAL 1 DAY
AND some_date < LAST_DAY(CURDATE() - INTERVAL 1 MONTH) + INTERVAL 1 DAY
So if CURDATE() is today, 2019-02-06, then:
- INTERVAL 2 MONTH is 2018-12-06
LAST_DAY() of that date is 2018-12-31
+ INTERVAL 1 DAY is 2019-01-01
Then the upper bound is:
- INTERVAL 1 MONTH is 2019-1-06
LAST_DAY() of that date is 2019-1-31
+ INTERVAL 1 DAY is 2019-02-01
The dates should be strictly less than 2019-02-01.
Using less than accounts for timestamps in the last second of the month, between 23:59:59.000 and 23:59:59.999.

comparing dates by month and year in mysql

I have a table containing data about events and festivals with following columns recording their start and end dates.
Start_Date
End_Date
date format is in YYYY-MM-DD. I need to fetch event details with the following condition.
Need to fetch all events which start with a current month and there end dates can be anything say currentDate+next30days.
I am clear about end date concept. but not sure how I can fetch data whose start dates are in a current month.
For this, I need to compare current year and current month against the Start_Date column in my database.
Can anyone help me to point out as how I can do that?
select * from your_table
where year(Start_Date) = year(curdate())
and month(Start_Date) = month(curdate())
and end_date <= curdate() + interval 30 day
I don't like either of the other two answers, because they do not let the optimizer use an index on start_date. For that, the functions need to be on the current date side.
So, I would go for:
where start_date >= date_add(curdate(), interval 1 - day(curdate()) day) and
start_date < date_add(date_add(curdate(), interval 1 - day(curdate()) day), interval 1 month)
All the date functions are on curdate(), which does not affect the ability of MySQL to use an index in this case.
You can also include the condition on end_date:
where (start_date >= date_add(curdate(), interval 1 - day(curdate()) day) and
start_date < date_add(date_add(curdate(), interval 1 - day(curdate()) day), interval 1 month)
) and
end_date <= date_add(curdate(), interval 30 day)
This can still take advantage of an index.
DateTime functions are your friends:
SELECT
*
FROM
`event`
WHERE
(MONTH(NOW()) = MONTH(`Start_Date`))
AND
(`End_Date` <= (NOW() + INTERVAL 30 DAY))
AND
(YEAR(NOW()) = YEAR(`Start_Date`))
Comparing the year and month separately feels messy. I like to contain it in one line. I doubt it will make a noticeable difference in performance, so its purely personal preference.
select * from your_table
where LAST_DAY(Start_Date) = LAST_DAY(curdate())
and end_date <= curdate() + interval 30 day
So all I'm doing is using the last_day function to check the last day of the month of each date and then comparing this common denominator. You could also use
where DATE_FORMAT(Start_Date ,'%Y-%m-01') = DATE_FORMAT(curdate(),'%Y-%m-01')

MySQL query to get data for the last week

I want to run a MYSQL query to get data for the previous week. The datatype for the date column is DATETIME. Could anyone suggest?
SELECT *
FROM calendar
WHERE dt BETWEEN CURDATE()-INTERVAL 1 WEEK AND CURDATE();
Here is an another version:
SELECT * FROM table WHERE
YEARWEEK(`date`, 1) = YEARWEEK( CURDATE() - INTERVAL 1 WEEK, 1)
SELECT id FROM tbl
WHERE date >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND date < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY
Here is the solution I find most reliable for getting data between the previus monday to the current monday. (That is what most people mean when the say past week, but not all, and that reflect in mysql).
SELECT
*
FROM
table
WHERE
date BETWEEN
(CURDATE() - INTERVAL 1 DAY) + INTERVAL -1 WEEK - INTERVAL WEEKDAY((CURDATE() - INTERVAL 1 DAY)) DAY
and
(CURDATE() - INTERVAL 1 DAY) + INTERVAL 0 WEEK - INTERVAL WEEKDAY((CURDATE() - INTERVAL 1 DAY)) DAY
It's also easy to change it for another week intervall
Make variable for current datetime - 1 week and make this query:
SELECT * FROM table WHERE date > $datatime

How do I get Timestamp minus 6 weeks in MySQL?

I have a field named timestamp. This is the last time a member was logged in.
I am looking to include a where clause in a query for something like
WHERE timestamp > todays date - 6 weeks
How would I do this?
I am trying to only include users that have logged in in the last 6 weeks.
Thanks
I find this syntax more readable than date_sub, but either way works.
WHERE timestamp >= NOW() - INTERVAL 6 WEEK
If you want to go by "Today" (midnight) instead "now" (current time), you would use this
WHERE timestamp >= DATE(NOW()) - INTERVAL 6 WEEK
where column>=date_sub(now(), interval 6 week)
This link demonstrates how you might acquire a timestamp of yesterday using the format DATE_ADD(CURDATE(), INTERVAL -1 DAY), therefore your query would probably be:
WHERE timestamp > DATE_ADD(CURDATE(), INTERVAL -42 DAY)
You can use between and now():
select somevalue
from yourtable
where yourtimestamp between now() - interval 1 day and now()
for TIMESTAMP there is a TIMESTAMPADD() function
SELECT TIMESTAMPADD(WEEK, -6, CURRENT_TIMESTAMP)
this will return the timestemp of 6 weeks ago
or in the case like the question
SELECT * FROM users
WHERE lastlogin > TIMESTAMPADD(WEEK, -6, CURRENT_TIMESTAMP)
Any luck yet. Have you tried:
>= DATE_SUB(NOW(), INTERVAL 6 WEEK)