SQL Query: Get Latest N days of datetime values in Timezone - mysql

I have a table Events
name VARCHAR(255)
dt_start DATETIME (stored in UTC)
dt_end DATETIME (stored in UTC)
I need to query Events in the table for the latest N days based on dt_start and a Timezone conversion. There can be multiple Events per day. I.e., Give me the latest 10 days of events in Timezone: America/New_York without respect to today().
I'm looking for the query to return the latest records no matter how far in the past or future they are but based on the number of days the Events dt_start span.
I could get the result with two queries, the first to find the maximum dt_start in the given Timezone. Then, subtract N days from that value and execute a second query to get all the events with dt_start greater than or equal to the value. Or, potentially, use sub-queries to achieve the same result. I'm looking for a slick way to do it with a single, fast query.

Related

Calculate the difference in hours between two String dates in MySQL?

I have two String columns in MySQL database. Those two columns were populated from a Java program in following way:
System.currentTimeMillis(); //first column
System.currentTimeMillis(); + someStringHours //second column; the String, someStringDays reprensents some number of days, let's say 5 hours in millis...
Which function in MySQL can be used to calculated the difference to get number of hours between these two columns?
You call them string dates but they are actually UNIX timestamps in milliseconds (also called Javascript timestamps). That's what System.currentTimeMillis() generates. It's a Java long data item, and a MySQL BIGINT data item. You can store it in a string. (You can store it that way if you must, but searching and sorting numbers stored as strings is an unreliable mess; beware!)
A typical Javascript timestamp (or UNIX timestamp in milliseconds) is a big integer like 1600858176374456. 1 600 858 176 374 456.
You can convert such a timestamp to a MySQL TIMESTAMP value with FROM_UNIXTIME() like this
FROM_UNIXTIME(column * 0.001)
Why multiply the column value by 0.001 (that is, divide it by 1000)? Because FROM_UNIXTIME() takes the timestamp in seconds, whereas System.currentTmeMillis() generates it in milliseconds.
Then you can use DATEDIFF() like this
DATEDIFF(FROM_UNIXTIME(laterTs*0.001),FROM_UNIXTIME(earlierTs*0.001))
This gives an integer number of days.
If you need the time difference in some other unit, such as hours, minutes, or calendar quarters, you can use TIMESTAMPDIFF(). This gives you your difference in hours.
TIMESTAMPDIFF(HOUR,
FROM_UNIXTIME(laterTs*0.001),
FROM_UNIXTIME(earlierTs*0.001));
You can use SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, or YEAR as the time unit in this function.
Pro tip: Use your DBMS's date arithmetic functions if you possibly can. They've worked out all sorts of edge cases for you already.
And, by the way, if you declare your columns like this (Timestamp with a millisecond precision: How to save them in MySQL):
laterTs TIMESTAMP(3),
earlierTs TIMESTAMP(3),
You'll have an easier time indexing on and searching by these times.
SELECT (1600858176374-1600944576374)/(24*60*60*1000) as Days
Where (1600858176374-1600944576374) are timestamps and (246060*1000) is a mills in day

UNIX Timestamp Time Difference Average MYSQL

I am currently working on a ticket system in which I would like to work out the average amount of time it is taking staff to respond to tickets.
I have 2 columns that hold the UNIX timestamps: timestamp (when ticket was submitted) and endstamp (when ticket was closed)
SELECT AVG(TIMEDIFF(endstamp,timestamp)) AS timetaken FROM `tickets`
I'm not really sure what I am doing wrong.
Any help would be much appreciated!
A UNIX timestamp is just a representation of a point in time as a number of seconds, so basically an integer value. On the other hand, date function timestampdiff() operates on 3 parameters: a unit, and two values (or expressions) of datetime datatype (or the-like). Your query should actually raise a syntax error, since what you are giving as first argument is not a legal unit.
If you want the difference in seconds between two UNIX timestamps, just substract them, so:
SELECT AVG(endstamp - timestamp) AS timetaken FROM `tickets`

given the start date & current date, how do i know if the current date is part of recurrence pattern

So I have a row which shows when it was created! (i.e. 12/1/2013), and I have recurring patterns with frequencies associated with it.
Frequencies are from 1 to 6 and Recurring Patterns are Daily, Weekly, Monthly, and Yearly.
So users can set up recurring like {Frequency:1, Recurrence: Monthly} or {Frequency:2, Recurrence: Monthly}
I need a query that will take the current and the created date, and see if current date falls under the frequency.
so if the Created Date: 12/1/2013, and Today: 2/1/2014, the {frequency: 2, Recurrence: Monthly} would be valid.
try this sqlFiddle it uses a function that checks to see if the given date is recurring for each row in schedule
Assuming:
Recurrence has days associated and is stored in the database as daily=1, week=7, month=31, yearly=365
That you want valid or invalid returned
That your dates are in standard mysql date format
Then the below will work:
To get the difference in days between two dates use the DATEDIFF() function
To get the absolute value of an int use the ABS() function
To get the remainder of a dividend and divisor use the MOD() function
Here is some example code:
SELECT
IF(MOD((ABS(DATEDIFF(createdDate,'2014-02-01'))/days),frequency)=0,'valid','invalid') AS result
FROM
schedule
INNER JOIN recurringtypes ON schedule.recurringtypeId=recurringtypes.id
EDITED: SQLFiddle

Getting week started date using MySQL

If I have MySQL query like this, summing word frequencies per week:
SELECT
SUM(`city`),
SUM(`officers`),
SUM(`uk`),
SUM(`wednesday`),
DATE_FORMAT(`dateTime`, '%d/%m/%Y')
FROM myTable
WHERE dateTime BETWEEN '2011-09-28 18:00:00' AND '2011-10-29 18:59:00'
GROUP BY WEEK(dateTime)
The results given by MySQL take the first value of column dateTime, in this case 28/09/2011 which happens to be a Saturday.
Is it possible to adjust the query in MySQL to show the date upon which the week commences, even if there is no data available, so that for the above, 2011-09-28 would be replaced with 2011/09/26 instead? That is, the date of the start of the week, being a Monday. Or would it be better to adjust the dates programmatically after the query has run?
The dateTime column is in format 2011/10/02 12:05:00
It is possible to do it in SQL but it would be better to do it in your program code as it would be more efficient and easier. Also, while MySQL accepts your query, it doesn't quite make sense - you have DATE_FORMAT(dateTime, '%d/%m/%Y') in select's field list while you group by WEEK(dateTime). This means that the DB engine has to select random date from current group (week) for each row. Ie consider you have records for 27.09.2011, 28.09.2011 and 29.09.2011 - they all fall onto same week, so in the final resultset only one row is generated for those three records. Now which date out of those three should be picked for the DATE_FORMAT() call? Answer would be somewhat simpler if there is ORDER BY in the query but it still doesn't quite make sense to use fields/expressions in the field list which aren't in GROUP BY or which aren't aggregates. You should really return the week number in the select list (instead of DATE_FORMAT call) and then in your code calculate the start and end dates from it.

Querying results on timestamp in mysql

I have series of records in a table called 'hits' and each record has the current_timestamp (ie. 2010-04-30 10:11:30) in a column called 'current_time'.
What I would like to do is query these records and return only the records from the current month. I cannot seem to get this to work.
I have tried a range of queries that don't work such as -
Select * FROM hits WHERE MONTH(FROM_UNIXTIME(current_time)) = 4
I don't know if I am even on the right lines!
Can anyone point me in the right direction?
Cheers.
WHERE MONTH(current_time) = 4
as your timestamp is not a unix one.
also I suppose you want to check YEAR() as well
for the current period you can use corresponding function applied to the curdate() function, so, no need to explicitly set current month number