user | completed
mike | 2016-07-10 19:00:00
john | 2016-07-11 08:00:00
I am trying to select all rows in a database where the row completed is NOT between 14:00 the previous day and the current day before 10:00. The script is designed to be run at 10:30 everyday
I've tried this
SELECT name FROM daily_tracking WHERE completed NOT BETWEEN now() - interval 1 day AND NOW() - INTERVAL 8 hour
you should use date_sub
SELECT name
FROM daily_tracking
WHERE completed NOT BETWEEN date_sub(NOW(), interval 1 day )
AND date_sub(NOW(), INTERVAL 8 hour)
I would not depend on the exact time when the script is being run. Instead, use arithmetic based on the current date:
SELECT dt.name
FROM daily_tracking dt
WHERE completed < date_sub(curdate(), interval (24 - 14) hour) or
completed > date_add(curdate(), interval 10 hour);
This will work on a given day, regardless of the time the script is run.
You can also write it this way, which I prefer...
SELECT dt.name
FROM daily_tracking dt
WHERE dt.completed BETWEEN CURDATE() - INTERVAL 14 HOUR AND CURDATE() + INTERVAL 10 HOUR;
Related
I'm trying to select all rows that have a date greater than or equal to the previous Sunday at 8 PM. So, if it were 7 PM on a Sunday right now, the selection would contain almost a full week of data. And if it were 9 PM on a Sunday right now, the selection would contain about an hour's worth of data.
So the following query isn't what I'm interested in, because it doesn't start and end on Sunday at 8 PM.
SELECT * FROM table WHERE date >= DATE_SUB(NOW(), INTERVAL 1 WEEK)
I'm not sure how to do write the correct query though.
You can use the cast statement to tweak the logic when your criteria matches.
Change the time Interval accordingly. I didn't added seconds so both the conditions will take 8 PM data.
SELECT * FROM table
WHERE date >= select CASE WHEN (DAYOFWEEK(NOW()) = 1 AND CURTIME() >= '20:00:00') THEN DATE(NOW()) + INTERVAL 20 HOUR
WHEN (DAYOFWEEK(NOW()) = 1 AND CURTIME() <= '20:00:00') THEN DATE_ADD(DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())+6 DAY), interval 20 hour)
ELSE DATE_ADD(DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())-1 DAY), interval 20 hour) END
I'm trying to do a query in MYSQL selecting orders where the created_at datetime is between the previous 3:00 in the morning and the next 3:00 in the morning.
For example: if I make that query at 2020-03-31 11:00:00, it should show me all the orders where the created_at timestamp are between 2020-03-31 03:00:00 and 2020-04-01 03:00:00.
I've tried to make this by using this query:
select *
from "orders"
where "created_at" BETWEEN cast(curdate() as datetime) + interval 3 hour
and cast(curdate() as datetime) + interval 1 day + interval 3 hour
but that doesn't work correctly because if i execute this query between 0:00 and 3:00 in the morning (For example at 2020-03-31 00:30:00), it won't show anything, but it should show me all the orders where the created_at timestamp are between 2020-03-30 03:00:00 and 2020-03-31 03:00:00.
Any idea of how to do that? I've been trying to find a solution for 2 hours a i couldn't find the right query to do so.
I would do:
created at >= date(now()- interval 3 hour) + interval 3 hour
and created_at < date(now()- interval 3 hour) + interval 3 hour + interval 1 day
The logic is to offset the current date and time by 3 hours, remove the time component, and then add 3 hours.
Then you could do
select ...
where `created_at` BETWEEN DATE_SUB(concat(CURDATE(), ' 03:00:00'), INTERVAL 1 DAY)
AND concat(CURDATE(), ' 03:00:00');
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.
I'm trying to make a query that will select all my users who's donor status is ending within 10 days.
As i only want to send the message once I want to select all the users who has their donor status ending between 10 and 9 days ahead.
The Donor end date is in this format: 0000-00-00 00:00:00
This is the query I'm currently working around with:
SELECT UserID FROM users_info WHERE donorEnd BETWEEN (NOW() + INTERVAL 10 DAY) AND (NOW() + INTERVAL 9 DAY)
I think you problem is that you are adding a time not a date: NOW() + INTERVAL 9 DAY = 2015-02-27 19:19 not 2015-02-27 00:00
Try use ADDDATE with CURDATE():
SELECT UserID FROM users_info WHERE donorEnd BETWEEN DATE_ADD(CURDATE(), INTERVAL 9 DAY) AND DATE_ADD(CURDATE(), INTERVAL 9 DAY)
So, I can do the following to get data from last week.
select * from table where week(date)=week(curdate())-1
Same for 2 weeks ago. But this fails if the data is in the prior year. What query can I use to get data from n weeks ago regardless of what year the data belongs to.
Edit: The week starts on Sunday 12AM and ends Saturday 11:59PM
When does a "week" start? Sunday? Monday? The same day of week as today?
Assuming you are happy with the last option, do this:
SELECT ...
WHERE date >= CURDATE() - INTERVAL $n WEEK
AND date < CURDATE() - INTERVAL $n-1 WEEK
Example
mysql> SELECT CURDATE(), CURDATE() - INTERVAL 9 WEEK, CURDATE() - INTERVAL 9-1 WEEK;
+------------+-----------------------------+-------------------------------+
| CURDATE() | CURDATE() - INTERVAL 9 WEEK | CURDATE() - INTERVAL 9-1 WEEK |
+------------+-----------------------------+-------------------------------+
| 2015-02-22 | 2014-12-21 | 2014-12-28 |
+------------+-----------------------------+-------------------------------+
If you need the week to start on a particular DOW, the query is messier, by further subtracting INTERVAL DAYOFWEEK(CURDATE()) DAY. And that could be off a little.
The start of the current week (assuming it is Sunday) is CURDATE() - INTERVAL (WEEKDAY(CURDATE() + INTERVAL 1 DAY)). So, replace CURDATE() in the above expression (twice) with this long mess.