SQL Query to only exclude data of last 24 hours? - mysql

I have the following data:
Table Name: NODE
NID | Name | Date
001 | One | 1252587739
Date is a unix timestamp. I need a query, whereby I can select only the nodes who's "Date" is older than 24 hours. Something like this:
SELECT * FROM NODE WHERE Date < NOW() - SOMETHING
Anybody know how to do this?
Does the NOW() - SOMETHING part take into account that the date is stored as a unix timestamp?

Unix timestamp is in seconds. This works with MySQL:
SELECT * FROM NODE WHERE Date < (UNIX_TIMESTAMP(NOW()) - 24*60*60)

where datediff(hh, date, now()) < 24

Going by the definition of "Unix Timestamp = number of seconds from Jan 1, 1970", and based on MS SQL Server (7.0 and up compatible):
SELECT *
from NODE
where datediff(ss, dateadd(ss, Date, 'Jan 1, 1970'), getdate()) < 86400
The innermost parenthesis adds the number of seconds to Jan 1 1970 to get the row's datetime in SQL server format, the outer parenthesis gets the number of seconds between that date and "now", and 86400 is the number of seconds in 24 hours. (But double-check this--I can't debug this just now, and I might have the function paramater order mixed.)

Related

How to group MYSQL Timestamps by local TZ "day"

I have big table (100M+ rows) with Timestamps (GMT) in microseconds as PK and values for that Timestamp.
I would like to get MAX values for days (in period), but "Day" must consider clients local TZ offset.
I tried:
CREATE TEMPORARY TABLE TBASE
SELECT
FLOOR(Timestamp / (86400 * 1000)) * 86400 as ts,
value
FROM mytable
WHERE Timestamp BETWEEN [GmtTimestampStart] and [GmtTimestampEnd]
And then:
SELECT
ts * 1000 as start_of_the_day_timestamp,
MAX(value)
FROM TBASE
GROUP BY start_of_the_day_timestamp
This works ofcourse only for +00:00 TZ.
But if client is in let's say -03:00 TZ:
Client sends correct Timestamp for TEMPORARY TABLE query, for example, if i want to query from start of the day 2021-01-04 to end of the day 2021-01-07, TS will be:
start: 1609729200000 (GMT: 2021-01-04 3:00:00.000)
end: 1610074799999 (GMT: 2021-01-08 2:59:99.999)
How can i get Max values for "local" days?
Above query gives results grouped by GMT time, not local; It rounds to 2021-01-04 00:00:00 GMT to 2021-01-08 00:00:00.
I tried to add TZ hours to TEMPORARY TABLE:
CREATE TEMPORARY TABLE TBASE
SELECT
FLOOR(Timestamp / (86400 * 1000)) * 86400 + 3*3600 as ts,
value
FROM mytable
WHERE Timestamp BETWEEN [GmtTimestampStart] and [GmtTimestampEnd]
but i gives me wrong results because, for example, if MAX value for local date 2021-01-04 is at 23:00:00 in GMT it is 2021-01-05 02:00:00 so i'm missing that value
Excuse my english, but i tried to explain as much as possible.

MySQL query or procedure to return table from values computed over multiple rows

I have a network created MYSQL table with following fields:
IP_SRC, IP_DST, BYTES_IN, BYTES_OUT, START_TIME, STOP_TIME
1.1.1.1 8.8.8.8 1080 540 1580684018 1580684100
8.8.4.4 1.1.1.1 2000 4000 1580597618 1580597800
The TIME values are epoch time ticks and each record is basically one TCP session.
I would like formulate a query (or procedure) to return a table with the following fields:
DayOfMonth, TotalOutBytes
1 12345
2 83747
3 2389
where DayOfMonth is the last 14 days or a range of last "n" days (or to keep the focus on the main problem assume the values are 1, 2, 3 of Feb 2020). The challenge is to grab all rows from the network table where STOP_TIME falls within the timeticks for DayOfMonth value for that row and sum up the BYTES_OUT to report as TotalOutBytes for that date.
I'm afraid I'm somewhat new to MYSQL and hopelessly lost.
Consider:
select
day(from_unixtime(stop_time)) dayOfMonth,
sum(bytes_out) TotalOutBytes
from mytable
where stop_time >= unix_timestamp(current_date - interval 14 day)
group by day(from_unixtime(stop_time))
Rationale:
the where clause uses unix_timestamp() to generate the unix timstamp corresponding to 14 days before the current date, which we can use to filter the table
from_unixtime() turns an epoch timestam pto a datetime value, then day() gives you the day number for that point in time
you can then aggregate with that value and sum bytes_out per group

issue with sql query to fetch records before current date and time

I have SQL structure like Name,expire_date,_expire_time
and I want the query to fetch records before the current date and time.
and for that, I have used
SELECT *
FROM table_name
WHERE expire_date <= CURDATE() AND expire_time <= CURTIME()
and I have received data like this image
as per this, I have received date before today like 2020-02-04 but with that, I have received data of 2020-02-03 because its time is before execution time
but I want data before the current date and time can anybody help me with this
You need to create a DATETIME value out of your DATE and TIME values (which you can do using TIMESTAMP), and then compare that to NOW() e.g.
SELECT *
FROM table_name
WHERE TIMESTAMP(expire_date, expire_time) <= NOW()
You can use
DATEDIFF
SELECT * FROM test WHERE DATEDIFF(expiry_date,CURDATE())>=0 AND expiry_time <= CURTIME();
Output
2020-02-04 05:00:00
2020-02-04 02:53:46

mySQL need timezone displayed in EST but cannot change global time settings

I am facing an odd issue. The global timezone setting in the mySQL is in UTC. There are multiple tables (sub databases) within a single instance of mySQL (I am using database.NET as the manager); so I can't change the global timezone.
The following is my query. All I need is to display the times in EST. I have seen a few solutions with ##sessionTimeZone but they didn't work. Furthermore, I am running into the issue of data being collected till 9PM EST, but in UTC that's 1AM on the next day.
My main confusion is that the data is already stored in the table in UTC; however, I would like to see those datetime fields displayed in EST.
cartId is a numerical field
createDate is a datetime field
I am just using http://fishcodelib.com/database.htm and connecting to the mySQL database.
SELECT DATE(createDate)
,DATE_FORMAT(createDate, '%l%p') as HourOfDay
,count(cartId) as numCarts_ALL
FROM carts
WHERE createDate >= '2014-09-24'
AND createDate < '2014-10-01'
AND HOUR(createDate) >= 10 AND HOUR(createDate) <21
GROUP by DATE(createDate),HOUR(createDate)
;
I will really appreciate any help.
Thanks again
DATETIME data types are not affected by either the global or connection-local timezone setting. That only works for TIMESTAMP data types. That explains why your attempts to muck around with ##session.TimeZone don't have any effect. NOW() and CURDATE() are affected, though.
You say your DATETIME data is stored in UTC. That's excellent. Life is much easier when you store your data that way.
Before you use the advice I'm about to give you, please make sure your MySQL server has its timezone tables loaded correctly. Do this command and make sure you don't get a NULL result.
SELECT CONVERT_TZ(NOW(), 'America/New_York', 'UTC')
If this doesn't work -- if you get a NULL or an error -- you need to get your server people to load the time zone tables. They should do this. They know how. (If they don't, you should get a new service provider.)
We need to use the timezone named 'America/New_York' because presumably you want to switch automatically between EDT and EST on the appropriate dates each year.
Now, to retrieve a correctly converted UTC DATETIME value from a table, you do this:
SELECT CONVERT_TZ(createDate, 'UTC', 'America/New_York') AS createDate
FROM yourTable
This is cool because you can make the timezone setting a user preference if you have users in various time zones.
To store a local time value as UTC just do it in reverse. For example.
INSERT INTO yourTable (createDate) VALUES (CONVERT_TZ(?, 'America/New_York', 'UTC'))
Now do
SELECT NOW()
and look to see whether NOW() is in local time or in UTC. If it is in UTC, then you should start your session by doing SET TIME_ZONE='America/New_York' . This will get your timezone set right so NOW() and CURDATE() do what you want.
Then, to fetch yesterday's (local time) rows from your table do this:
WHERE createDate >= CONVERT_TZ(CURDATE(),'America/New_York','UTC') - INTERVAL 1 DAY
AND createDate < CONVERT_TZ(CURDATE(),'America/New_York','UTC')
This will convert midnight local time to UTC and fetch the range of items.
To get all the data from 4pm today until 2am tomorrow, you could do this:
4pm today (localtime) is CURDATE() + INTERVAL 16 HOUR . 2am tomorrow is CURDATE() + INTERVAL 26 HOUR or you could write it CURDATE() + INTERVAL 1 DAY + INTERVAL 2 HOUR
So fetching that range would need this:
WHERE createDate >= CONVERT_TZ(CURDATE() + INTERVAL 16 HOUR,'America/New_York','UTC')
AND createDate < CONVERT_TZ(CURDATE() + INTERVAL 26 HOUR,'America/New_York','UTC')
You could also use ADDTIME(CURDATE(),'16:00') to obtain a DATETIME value for 4pm today, if you'd rather combine ordinary date objects and ordinary time objects. Similarly, you could get 2am tomorrow like this:
ADDTIME(CURDATE(),'02:00') + INTERVAL 1 DAY
Notice that this form of WHERE clause allows a range scan on an index on the createDate column. This is very good for performance.
To convert datetime from a timezone to another timezone:
SELECT DATE(CONVERT_TZ(createDate, '+00:00', '-04:00')) createdDate,
HOUR(CONVERT_TZ(createDate, '+00:00', '-04:00')) hourOfDay
FROM carts
WHERE
createDate BETWEEN CURRENT_DATE + INTERVAL 16 HOUR AND CURRENT_DATE + INTERVAL 26 HOUR
GROUP BY createdDate, hourOfDay
For different dates
SELECT DATE(CONVERT_TZ(createDate, '+00:00', '-04:00')) createdDate,
HOUR(CONVERT_TZ(createDate, '+00:00', '-04:00')) hourOfDay
FROM carts
WHERE
createDate BETWEEN '2014-09-24' AND '2014-10-01'
GROUP BY createdDate, hourOfDay
HAVING hourOfDay <= 2 OR hourOfDay >= 20
You might think "why not in WHERE clause?"
If functions are used in the where clause, indexes can't be used (which results in a full table scan). So just filter out the records within the daterange, and the hours in the HAVING clause
FYI
CURRENT_DATE + INTERVAL 16 HOUR
Is short for
DATE_ADD(CURRENT_DATE, INTERVAL 16 HOUR)

How can I exclude upper limit in BETWEEN sql server

I am using SQL Server as my database. I am searching for a row for the date that I have entered. This means searching rows where submission_date is exactly '12/13/2011'. First I am converting the search criteria date to milliseconds
i.e.
Dec 13 2011 00:00:00 ='1323727200000'
Dec 14 2011 00:00:00 ='1323813600000'`
SELECT *
FROM log_file
WHERE submission_date BETWEEN '1323727200000' AND '1323813600000'
This query will search for Dec 13 Midnight to Dec 14 Midnight, but I want to skip the upper limit value i.e. from Dec 13 2011 00:00:00 to Dec 13 2011 59:59:59. For this I thought to use >= and <. Is this a right approach?
Having done this, I have a iBatis xml where I am writing the following which is giving me error.
<isNotEmpty prepend="AND" property="submissiondate">
submission_date <![CDATA[ >= ]]> #submissiondate # AND <![CDATA[ < ]]> #submissiondate #
</isNotEmpty>
Please suggest if this is the right approach.
Thanks
Yes, you'd use >= and < typically for time/date range queries
Alternatively, you could subtract 3 milliseconds from the upper limit to get the highest datetime (not newer datetime2) value for that day (xxx 23:59.59.997)
SELECT * FROM log_file
WHERE submission_date BETWEEN 1323714600000 AND 1323801000000-3
Note: subtracting 1 would probably be OK if everything is milliseconds...
Edit, example of why 3ms
SELECT
DATEADD(millisecond, -1, '20111214'), -- 2011-12-14 00:00:00.000
DATEADD(millisecond, -2, '20111214'), -- 2011-12-13 23:59:59.997
DATEADD(millisecond, -3, '20111214') -- 2011-12-13 23:59:59.997
And interestingly, are you sure this is midnight?
For 1323813600 seconds, I get 2011-12-13 22:00:00
On SQL Server:
SELECT DATEADD(second, 1323813600, '19700101')
On MySQL
SELECT FROM_UNIXTIME(1323813600)
In your case, where "date" seems to be of type BIGINT, why not just subtract 1 from the upper interval limit?
SELECT * FROM log_file
WHERE submission_date BETWEEN 1323714600000 AND 1323801000000 - 1
Of course, this wouldn't work with floating point numbers or decimals...
Yes, if you have to skip the upper limit - you should use
WHERE Date >= '20111213' AND Date < '20111214'
Of course - if your column's type is DATETIME