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)
Related
I am trying to get back rows that are between year ranges, such as from 0-5 years, 5-10 years, 10-15 etc.
So far, I've only been able to product between 0-5 but need some help on querying between 5-10 years etc.
SELECT *
FROM users
WHERE start_date >= DATE_SUB(NOW(),INTERVAL 5 YEAR)
I've tried using the BETWEEN function, but could be using it incorrectly. Open to suggestions.
I'm not a fan of hard coding values in for the dates because I don't want to go back every few years and change it.
Assuming start_date is DATE datatype (not DATETIME or TIMESTAMP)
five years ago up to today
WHERE start_date > DATE(NOW()) + INTERVAL -5 YEAR
AND start_date <= DATE(NOW()) + INTERVAL 0 YEAR
ten years ago up to five years ago
WHERE start_date > DATE(NOW()) + INTERVAL -10 YEAR
AND start_date <= DATE(NOW()) + INTERVAL -5 YEAR
You can use BETWEEN.
SELECT *
FROM users
WHERE (start_date BETWEEN NOW() AND DATE_SUB(NOW(), INTERVAL 5 YEAR))
and then for your next interval:
SELECT *
FROM users
WHERE (start_date BETWEEN DATE_SUB(NOW(), INTERVAL 5 YEAR) AND DATE_SUB(NOW(), INTERVAL 10 YEAR))
0 - 5
SELECT * FROM users
WHERE
start_date BETWEEN (CURDATE() - INTERVAL 5 YEAR) AND CURDATE();
5 - 10
SELECT * FROM users
WHERE
start_date BETWEEN (CURDATE() - INTERVAL 10 YEAR) AND (CURDATE() - INTERVAL 5 YEAR);
10 - 15
SELECT * FROM users
WHERE
start_date BETWEEN (CURDATE() - INTERVAL 15 YEAR) AND (CURDATE() - INTERVAL 10 YEAR);
I have a table with the following data:
I am looking to group the rows into the following:
Within the last day (everything within the last 24 hours)
Within the last 7 days (everything within the last week)
Within the last 30 days (everything within the last month)
The end result for the above rows would look something like:
I can group the records into these brackets right now with:
SELECT (CASE WHEN created_at = CURDATE() THEN '1 Day'
WHEN created_at >= CURDATE() - INTERVAL 6 DAY THEN '7 Days'
WHEN created_at >= CURDATE() - INTERVAL 29 DAY THEN '30 Days'
END) AS Timeframe, COUNT(*) AS Count
FROM my_table
GROUP BY (CASE WHEN created_at = CURDATE() THEN '1 Day'
WHEN created_at >= CURDATE() - INTERVAL 6 DAY THEN '7 Days'
WHEN created_at >= CURDATE() - INTERVAL 29 DAY THEN'30 Days'
END)
But this will prevent individual records from being counted more than once. For example, lines 2 and 3 in the first picture needs to be counted in all three brackets (1 day, 7 days, and 30 days) - while lines 6 through 9 only needs to be counted in the 30 days bracket.
How would you do this with MySQL?
It is easiest to do this as columns, rather than rows:
SELECT SUM(created_at = CURDATE()) as today
SUM(created_at >= CURDATE() - INTERVAL 6 DAY) as last_7_days,
SUM(created_at >= CURDATE() - INTERVAL 29 DAY) as last_30_days,
SUM(created_at < CURDATE() - INTERVAL 29 DAY) as older
FROM my_table;
If you want your response in several rows, instead of just one with several columns, take #Gordon Linoff as your starting point... but perform the queries "one row at at time" (it won't be as efficient, because you visit the table 4 times instead of 1!):
-- Row for the 1 day timeframe
SELECT '1 Day' AS `Timeframe`, SUM(created_at = CURDATE()) AS `Count`
FROM my_table
UNION
-- Row for the 7 days timeframe...
SELECT '7 Days' AS `Timeframe`, SUM(created_at >= CURDATE() - INTERVAL 6 DAY) AS `Count`
FROM my_table
UNION
SELECT '30 Days' AS `Timeframe`, SUM(created_at >= CURDATE() - INTERVAL 29 DAY) AS `Count`
FROM my_table
UNION
SELECT 'Older' AS `Timeframe`, SUM(created_at < CURDATE() - INTERVAL 29 DAY) AS `Count`
FROM my_table ;
If you can use MariaDB instead of MySQL, you can use a WITH, which will allow the query to be efficient again:
WITH stats AS
(
SELECT SUM(created_at = CURDATE()) as today,
SUM(created_at >= CURDATE() - INTERVAL 6 DAY) as last_7_days,
SUM(created_at >= CURDATE() - INTERVAL 29 DAY) as last_30_days,
SUM(created_at < CURDATE() - INTERVAL 29 DAY) as older
FROM my_table
)
-- Convert to rows with negligible overhead
SELECT '1 Day' AS `Timeframe`, today FROM stats
UNION
SELECT '7 Days', last_7_days FROM stats
UNION
SELECT '30 Days', last_30_days FROM stats
UNION
SELECT 'Older', older FROM stats ;
In both cases, you'll get (as of 2017-07-25):
Timeframe | today
:-------- | ----:
1 Day | 0
7 Days | 4
30 Days | 8
Older | 0
dbfiddle here
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;
most of the results ive found while looking this up have been from getting a range of dates from today to say 30 days from now. Im just looking for the results that 14, 7, 3 and 1 day from today (each individualy)
Heres the sql i have so far
SELECT * FROM Location WHERE timestamp (CURDATE() + 14 Day)
that would be the sql to get all locations that have a timestamp that is 14 days from now (this is to send out a reminder newsletter fyi).
And it shouldnt matter what time of that day it is, if possible it should grab all timestamp results from that day
SELECT * FROM Location
WHERE DATE(timestamp) IN (
DATE_ADD(CURDATE(), INTERVAL 14 DAY),
DATE_ADD(CURDATE(), INTERVAL 7 DAY),
DATE_ADD(CURDATE(), INTERVAL 3 DAY),
DATE_ADD(CURDATE(), INTERVAL 1 DAY)
);
Reference: MySQL add days to a date
hoping you guys can help - I have a timestamp column in my db table and i want to run a query to find any records from that table where the timestamp is the same as 7 days from now (ignoring the hours, minutes and seconds). So far I have this but I'm certain it's not what i should be doing:
WHERE `import_date` = 'DATE_SUB(NOW(), INTERVAL 7 days)'
WHERE import_date = 'DATE_SUB(NOW(), INTERVAL 7 days)'
should be
WHERE import_date >= DATE_SUB(NOW(), INTERVAL 7 day)
days should be day
for timestamp same as 7 day before from now use
WHERE DATE_FORMAT(`import_date`, "%Y-%m-%d") = DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 7 day), "%Y-%m-%d")