how to Substrate 36 hours from date field in database - mysql

How can i display a range of date from my Date field in the database into a table?
I have a field called: Date from the database that Display the event date of 5 days. And I would like to display only 1 day and 12 hours (36 hours) using SQL Statement.
Field name : date, details from Events_new table. This table display 5 days of date and time records. and It's updates automatically. My point is that I need a SQL Query that will fetch the last 36 hours from the table
I tried many time. This is my SQl Statement but I can't get it right.
SELECT
details , datediff(date , interval 36 hour) as substratehours
FROM
events_new
WHERE
Stuff_id = 4932
order by date ASC
And This :
SELECT
date,
details
FROM
events_new
WHERE
stuff_id = 4932
AND date = (date - interval 36 hour)
And This:
SELECT
date,
details
FROM
events_new
WHERE
stuff_id = 4932
AND date > date_sub(date,interval 36 hour)
order by date ASC
I Still Don't get it right! Anyone with a subjection?
Thank you

To get the rows having date in the most recent 36 hours only:
SELECT details
FROM events_new
WHERE Stuff_id = 4932
AND `date` > date_sub(NOW(), INTERVAL 36 HOUR)
ORDER BY `date` ASC
If you don't want the 36 hours interval to end now but at some arbitrary moment in time then you should use BETWEEN to compare the value of field date with the interval bounds:
SELECT details
FROM events_new
WHERE Stuff_id = 4932
AND `date` BETWEEN date_sub('2015-01-19 12:00:00', INTERVAL 36 HOUR)
AND '2015-01-19 12:00:00'
ORDER BY `date` ASC
Replace '2015-01-19 12:00:00' with the moment when you want your 36 hours interval ends.
Take a look at MySQL documentation about the SELECT statement and date & time functions.

In mysql
SELECT DATE_ADD(date,INTERVAL -36 hour) AS date from events_new
In mssql
select DATEADD(hour , -36 , date )AS date from events_new

Related

SQL date not relative

I have a table in which i store every 15 minutes result of a cron job, which is nothing more than a timestamp, a population number and an id.
I am trying to query it as following.
SELECT ROUND(AVG(`population`),0) AS population, DATE(`time`) AS date
FROM `swg_servertracker`
WHERE `time` >= DATE(NOW()) - INTERVAL 7 DAY
GROUP BY DATE(`time`)
DESC
LIMIT 7
What it does it creates an daily average, and grabs the last 7 entries. Sadly in was not in the right order, so i flipped it to ascending. My problem is when i inverse (asc) it, it skips today, and goes back an extra day (today is the 3rd of october, which is not taken in the equation when i use the ascending)
I tried to set the where statement to just now - interval 168 hours (which is also 7 days but then relative back) which had no result either on this. Still it skips today and just goes back 7 days from on yesterday.
SELECT ROUND(AVG(`population`),0) AS population, DATE(`time`) AS date
FROM `swg_servertracker`
WHERE `time` >= NOW() - INTERVAL 168 HOUR
GROUP BY DATE(`time`)
ASC
LIMIT 7
So is there a way I can take today in account as well?
You select 8 records instead 7 records. If you want to select 7 latest records, you must use "greater than" sign instead "greater than or equal" sign.
SELECT ROUND(AVG(`population`),0) AS population, DATE(`time`) AS date
FROM `swg_servertracker`
WHERE `time` > NOW() - INTERVAL 7 DAY
GROUP BY DATE(`time`)
ASC
LIMIT 7
You can get the result-set in a Derived table, and do a sorting on the results again.
Note that, in MySQL, Aliases defined in the Select clause can be used in Group By, Having and Order By clauses. So, I have aliased DATE(time) to avoid re-computation in Group by and Order By.
You can do this instead:
SELECT dt.population,
dt.date1 AS date
FROM (
SELECT ROUND(AVG(`population`),0) AS population,
DATE(`time`) AS date1
FROM `swg_servertracker`
WHERE `time` >= DATE(NOW()) - INTERVAL 7 DAY
GROUP BY date1
ORDER BY date1 DESC
LIMIT 7
) AS dt
ORDER BY dt.date1 ASC

mysql optimize query where date hour

Hi all, I have pretty awfull query, that needs optimizing.
I need to select all records where date of created matches NOW - 35days, but the minutes and seconds can be any.
So I have this query here, its ugly, but working:
Any optimisation tips are welcome!
SELECT * FROM outbound_email
oe
INNER JOIN (SELECT `issue_id` FROM `issues` WHERE 1 ORDER BY year DESC, NUM DESC LIMIT 0,5) as issues
ON oe.issue_id = issues.issue_id
WHERE
year(created) = year( DATE_SUB(NOW(), INTERVAL 35 DAY) ) AND
month(created) = month( DATE_SUB(NOW(), INTERVAL 35 DAY) ) AND
day(created) = day( DATE_SUB(NOW(), INTERVAL 35 DAY) ) AND
hour(created) = hour( DATE_SUB(NOW(), INTERVAL 35 DAY) )
AND campaign_id IN (SELECT id FROM campaigns WHERE initial = 1)
I assume the field "created" is a datetime field and is from the issues table? Since you don't need anything else on the issues and campaign table, then you can do the following:
SELECT e.* FROM outbound_email e
JOIN issues i ON e.issue_id = i.issue_id
JOIN campaigns c ON c.id = i.campaign_id
WHERE i.created < DATE_SUB(NOW(), INTERVAL 35 DAY)
AND c.initial = 1
There's no need to separate the datetime field into years, months...etc.
You seem to be saying you want to select all rows from a table where the time they were created was the same hour as it is currently, 35 days ago
SELECT * FROM table WHERE created BETWEEN
DATE_ADD(CURDATE(), INTERVAL (HOUR(now()) - 840) HOUR) AND
DATE_ADD(CURDATE(), INTERVAL (HOUR(now()) - 839) HOUR)
Why does it work? Curdate gives us today at midnight. We add to this the current hour of the time (e.g. Suppose it's now 5pm we'd add `HOUR(NOW()) which would give us 17, for a time now of 5pm) but we also subtract 840 because that's 35 days * 24 hours a day = 840 hours. Date add will hence add -823 hours to the current date, i.e. 5pm 35 days ago
We make the search a range to get all the records from the hour, the simplest way to specify an hour later is to subtract 839 hours instead of 840
Technically this query will also return records that are bang on 6pm (but not a second later) 35 days ago too because between is inclusive (between 1 and 10 will return 10 also
If this is a problem, change the BETWEEN for created >= blah AND created < blahblah
I haven't put the rest of your query in for reasons of clarity
As a side note, the way you did it wasn't bad- you could have simplified things by not having the year/month/day parts, just dropping the time part of the date with date(created) = date_sub(curdate(), interval 35 day) which is the year month and day combined as a date, no time element.. BUT it is generally always best to leave table data alone rather than format or convert it just to match a query. If you convert table data then indexes can no longer be used. If you go the extra mile to get your query parameters into the format of the column, and don't convert the table data then indexes on the column can be used

Apply group by and limit offset together in MySQL

I have a table name transactions where data rows are stored with a date
Like
`trans_id` `amount` `tdate`
I want to filter that data like last 30 days, last 31st 60 days, last 61-90 days calculate the overall amount also
My queries are
For last 30 days
SELECT SUM(amount) AS amt FROM transactions GROUP BY DATE(tdate) ORDER BY DATE(tdate) DESC LIMIT 30
Working fine and show SUM of amount (last 30days)
But for last 31-60 days not working
SELECT SUM(amount) AS amt FROM transactions GROUP BY DATE(tdate) ORDER BY DATE(tdate) DESC LIMIT 60,31
How to solve it ? I do want to include only 31 to 60 days amount only
Use the following: (It returns data between today and last 30 days)
SELECT DATE_FORMAT(DateCol, '%m/%d/%Y')
FROM Table
WHERE DateCol BETWEEN CURDATE() - INTERVAL
30 DAY AND CURDATE()
Or more precisely, this will do the trick:
DateCol BETWEEN (NOW() - INTERVAL 60 DAY)
AND (NOW() - INTERVAL 30 DAY)
CURDATE() works for only date portion. If you have DateTime column, then NOW() will do.

SELECT FROM TABLE WHERE TIMESTAMP -> 21 Days from now

I have a table with some fields and a timestamp field named timestart.
What I would like to do is select all the records from my table where the field timestart is 21 days from now.
But how can I do this?
you can have this with. if you want exact equals to timestamp. use =
SELECT *
FROM table
WHERE date = DATE_ADD(NOW(), INTERVAL 21 DAY)
ORDER BY date DESC
you can achive the same by using
SELECT *
FROM table
WHERE date = DATE_ADD(NOW(), INTERVAL 21 DAY)
ORDER BY date DESC
The datediff function seems to meet the bill:
SELECT *
FROM my_table
WHERE DATE_DIFF (timestart, CURRENT_DATE()) >= 21
You can use this:
SELECT *
FROM table
WHERE date >= (NOW() - INTERVAL 21 DAY)
ORDER BY date DESC
LIMIT 20

Mysql DATE_SUB(NOW(), INTERVAL 1 DAY) 24 hours or weekday?

I am trying to get the total amount of registered users per day. At the moment I am using this:
$sql = "SELECT name, email FROM users WHERE DATE_SUB(NOW(), INTERVAL 1 DAY) < lastModified"
But I am not sure if this works per day or per 24 hours?
For example, a user who registered 22 hours ago shouldn't be returned. I just want the user of today(=Tuesday).
lastModified is, presumably, a datetime. To convert this into a date you can simply wrap it in DATE() i.e. DATE(lastModified). DATE() returns the date part of a datetime value which is effectively 00:00 on that day.
SELECT
name,
email
FROM users
WHERE DATE(lastModified) = DATE( DATE_SUB( NOW() , INTERVAL 1 DAY ) )
Using this to match a WHERE though would be inefficient as all rows would require DATE applied to them and so it would probably scan the whole table. It is more efficient to compare lastModified to the upper and lower bounds you are looking for, in this case >= 00:00 on SUBDATE(NOW(),INTERVAL 1 DAY) and < 00:00 on NOW()
Therefore you can use BETWEEN to make your select giving the following.
SELECT
name,
email
FROM users
WHERE lastModified
BETWEEN DATE( DATE_SUB( NOW() , INTERVAL 1 DAY ) )
AND DATE ( NOW() )
I think you need
SELECT
name,
email
FROM users
WHERE DATE(lastModified) = DATE( NOW() )
This effectively "rounds to the date only" and will therefore only match records "since midnight".