I am looking for a way to do something, I have never done before.
I have the Query as
SELECT DATE_FORMAT(CONVERT_TZ(pi.start,'+00:00','+10:00'), '%Y-%m-%d %h:%m:%s') as start,
ifnull(dc.name,'Unknown') as source,
format(sum(ifnull(pi.rev,0)),2) as revenue
from trk.provider_imp pi
left outer join trk.dsp_client dc
on pi.clientid = dc.id
and type = 'client'
where pi.start between DATE_SUB(DATE_FORMAT(NOW() ,'%Y-%m-01'), INTERVAL 5 MONTH) AND DATE_FORMAT(LAST_DAY(NOW() - INTERVAL 1 MONTH),'%Y-%m-%d')
and pi.status = 1
group by start,pi.clientid
order by pi.start, pi.clientid;
The above query works and I get the results that I desire, however, for the Time Zone Conversion, I am an hour behind, for Nov, Dec and Jan.
Is there a way where I could add a if statement, and that would do something like, if 'start' is in ('Nov 2014','Dec 2014', 'Jan 2015', than 'start' plus one hour)?
To do what you need, the simplest and most effective way I have found was to use your actual location as a parameter, and not the GMT offset.
For instance, if you are in Melbourne, instead of using '+10:00' in Winter and '+11:00' in Summer, you would simply mention 'Australia/Melbourne' in the timezone parameter. Doing this will take care of the daylight savings time offset.
Your example mentioned +10, I'm assuming Melbourne; these 2 statements will return different times as the DST offset is different:
SELECT CONVERT_TZ('2015-01-01 02:00:00','UTC','Australia/Melbourne');
SELECT CONVERT_TZ('2015-10-01 02:00:00','UTC','Australia/Melbourne');
The caveat is that standard MySQL installations do not come with the timezone names built-in.
Follow these instructions to get those in your MySQL server: http://dev.mysql.com/doc/refman/5.1/en/time-zone-support.html
Related
This is a question from leetcode, using the second query I got the question wrong but could not identify why
SELECT
user_id,
max(time_stamp) as "last_stamp"
from
logins
where
year(time_stamp) = '2020'
group by
user_id
and
select
user_id,
max(time_stamp) as "last_stamp"
from
logins
where
time_stamp between '2020-01-01' and '2020-12-31'
group by
user_id
The first query uses a function on every row to extract the year (an integer) and compares that to a string. (It would be preferable to use an integer instead.) Whilst this may be sub-optimal, this query would accurately locate all rows that fall into the year 2020.
The second query could fail to locate all rows that fall into 2020. Here it is important to remember that days have a 24 hour duration, and that each day starts at midnight and concludes at midnight 24 hours later. That is; a day does have a start point (midnight) and an end-point (midnight+24 hours).
However a single date used in SQL code cannot be both the start-point and the end-point of the same day, so every date in SQL represents only the start-point. Also note here, that between does NOT magically change the second given date into "the end of that day" - it simply cannot (and does not) do that.
So, when you use time_stamp between '2020-01-01' and '2020-12-31' you need to think of it as meaning "from the start of 2020-01-01 up to and including the start of 2020-12-31". Hence, this excludes the 24 hours duration of 2020-12-31.
The safest way to deal with this is to NOT use between at all, instead write just a few characters more code which will be accurate regardless of the time precision used by any date/datetime/timestamp column:
where
time_stamp >= '2020-01-01' and time_stamp <'2021-01-01'
with the second date being "the start-point of the next day"
See answer to SQL "between" not inclusive
I need to calculated difference in seconds between 2 dates. I cannot use TIMEDIFF because of its limitations.
When I use:
SELECT UNIX_TIMESTAMP('2015-03-28 08:21:15') - UNIX_TIMESTAMP('2015-03-27 08:21:15');
it returns expected 86400 seconds (what gives 24 hours) but when I use:
SELECT UNIX_TIMESTAMP('2015-03-29 08:21:15') - UNIX_TIMESTAMP('2015-03-27 08:21:15');
it seems it doesn't give 86400*2 but 169200 instead what gives 47 hours.
The question is - why is that? Is it a bug or feature? Is there any other reasonable way to calculate time difference not worrying about time limitations?
It looks like that in 2015 there was Daylight changing at 29 March, it could be the reason
Daylight saving 2015
There are a couple of ways in which this problem can be tackled:
With UNIX_TIMESTAMP():
Use SET SESSION time_zone = '+0:00' before carrying out date operations.
SET SESSION time_zone = '+0:00';
SELECT UNIX_TIMESTAMP('2015-03-29 08:21:15') - UNIX_TIMESTAMP('2015-03-27 08:21:15');
This returns 172800, i.e. a proper time difference of 48 hours.
Demo.
With TIMESTAMPDIFF():
If you don't wish to use SET SESSION time_zone, you could try TIMESTAMPDIFF()
SELECT UNIX_TIMESTAMP('2015-03-29 08:21:15') - UNIX_TIMESTAMP('2015-03-27 08:21:15');
SELECT TIMESTAMPDIFF(SECOND, '2015-03-27 08:21:15', '2015-03-29 08:21:15');
The first computation results in 169200 (i.e. 47 hours) and the second shows 172800 (i.e. 48 hours).
Remember though that the smaller timestamp should be used first in TIMESTAMPDIFF(), or you'd get a negative result. Alternatively, you could wrap TIMESTAMPDIFF() under ABS() as so:
SELECT ABS(TIMESTAMPDIFF(SECOND, '2015-03-29 08:21:15', '2015-03-27 08:21:15'));
Rextester link.
My table has the below mentioned timestamp
Outcome required: data between 1997 and 1999 morning times i.e. (12:00:01 to 11:59:59)
1997-09-22 18:02:38
1997-10-15 01:26:11
1997-11-03 02:42:40
1997-10-15 01:25:19
1999-10-15 01:25:19
1999-10-15 23:25:19
1998-03-12 20:15:12
1998-02-13 23:52:53
1997-09-23 23:26:01
2000-09-23 23:26:01
I am trying the below query but does not give the right outcome
SELECT * FROM r WHERE ts BETWEEN '1997-01-01 00:00:01' AND '1999-12-31 11:59:59'
I can find the outcome by extracting hours and minutes separately but is there a way where the query is a bit concise?
You need to extract date and time separately to fetch the needed data.
In MySql you can use DATE_FORMAT method to extract same.
Read more here: DATE_FORMAT(date, format)
Your query will be:
SELECT * FROM `r` WHERE DATE_FORMAT(ts, "%Y-%m-%d") BETWEEN '1997-01-01' AND '1999-12-31' AND DATE_FORMAT(date_time, "%H:%i:%s") BETWEEN '00:00:01' AND '11:59:59'
If your date is not in DateTime format then you need to convert your string/raw date to date time format using STR_TO_DATE method.
Read more here: STR_TO_DATE(date, format)
You may use STR_TO_DATE function :
SELECT *
FROM r
WHERE ts >= STR_TO_DATE('1997-01-01', '%Y-%m-%d')
AND ts < STR_TO_DATE('2000-01-01', '%Y-%m-%d')
P.S: ts <= '1999-12-31 11:59:59' implicitly means ts < '2000-01-01'
There's no way to specify particular hours of day within the range comparison that spans years. We'd need to add another predicate (condition) to narrow down the rows that match the range scan.
We can use DATE_FORMAT function to get hours, minutes and seconds (formatted with two digits each)
For example, based on the stated specification (only times between 00:00:01 and 11:59:59) we could add something like this:
AND DATE_FORMAT(r.ts,'%h:%i:%s') BETWEEN '00:00:01' AND '11:59:59'
But it seems really strange to be omitting the second right after midnight, and the second immediately before noon. (MySQL DATETIME can have resolution smaller than a second, up to six decimal digits.)
Personally, I'd identify "morning hours" as simply hour values between 0 and 11, like this:
AND DATE_FORMAT(r.ts,'%h') BETWEEN '00' AND '11'
That will include "morning times" before 12:01 AM and after 11:59 AM. For example, these times would be included by this condition, but be omitted by the first example condition:
00:00:00.555
11:59:59.023
The specification isn't entirely clear... determining whether these times should be included or excluded would help clarify the specification. I suspect the statement of the specification is somewhat jarbled, and we really want all "morning times" between midnight and noon.
SELECT r.*
FROM r
WHERE r.ts >= '1997-01-01'
AND r.ts < '2000-01-01'
AND DATE_FORMAT(r.ts,'%h) BETWEEN '00' AND '11'
But it really depends on the definition of "morning hours", whether that first second after midnight is included or excluded.
I was granted access to a legacy database in order to do some statistics work.
I've so far gotten everything I need out of it, except I am trying to calculate a distance in time, using 5 values, stored in 4 columns (ARGGGHHH)
Above is a subsection of the database.
As you can see, I have start and stop date and time.
I would like to calculate the distance in time from str_date + str_time to stp_date + stp_time
The issue I have is, the calculation should be performed differently depending on the second value in stp_time.
IFF second value = "DUR".... THen I can just take the first value "01:04:51" in this scenario
IFF second value = anything else. stp_time represents a timecode and not a duration. This must then calculate stp_time - str_time (accounting for date if not same date)
All data is 24 hour format. I have done work with conditional aggregation, but I have not figured this one out, and I have never worked with a malformed column like this before.
Any and all advice is welcome.
Thanks for reading
SELECT
CASE WHEN RIGHT(stp_time,3)="DUR"
THEN
TIMEDIFF(LEFT(stp_time,8), '00:00:00')
ELSE
TIMEDIFF(
STR_TO_DATE(CONCAT(stp_date," ",LEFT(stp_time,8)), '%d/%b/%Y %H:%i:%s'),
STR_TO_DATE(CONCAT(str_date," ",LEFT(str_time,8)), '%d/%b/%Y %H:%i:%s')
)
END AS diff
FROM so33289063
Try this out, you might want a where condition for the subquery
With left and right:
SELECT IF(dur,stp,timediff(str,stp)) FROM(
SELECT STR_TO_DATE(CONCAT(str_date," ",LEFT(str_time,8)), 'd%/%b/%Y %H:%i:%s') as str,
STR_TO_DATE(CONCAT(stp_date," ",LEFT(stp_time,8)), 'd%/%b/%Y %H:%i:%s') as stp,
if(RIGHT(stp_time,3)="DUR",1,0) as dur
FROM my_table
) AS times
I'm getting the above SQL error after executing this query.
SELECT r.SectionIDNum, r.PeopleIDNum, r.Completed, c.CourseID, s.DistrictIDNum, s.EndDate
FROM Registration r, Course c, Section s
WHERE r.SectionIDNum=s.SectionID AND c.CourseID=s.CourseIDNum AND r.Completed='Y'
AND s.EndDate between ('2012-06-31', 'yyyy-mm-dd') and ('2013-07-01', 'yyyy-mm-dd')
Apparently, the commas in the dates are causing the error but I don't know how to fix it.
June only has 30 days in it. So SQL Server is confused by your request to cast June 31 as a date.
This works fine:
SELECT CAST('2012-06-30' AS DATE)
One way to avoid end of month issues is to use the DATEADD() function, for example, to get one year and one day prior to July 1, 2013 like in your example:
SELECT DATEADD(day,-1,(DATEADD(year,-1,CAST('2013-07-01' AS DATE))))
Also, remember that BETWEEN is inclusive, so you're getting June 30 and July 1 in your example, perhaps just subtracting the year is sufficient.
Use the CAST() Function (CAST converts value of one data type to a different type. In this case, CHAR to DATETIME):
SELECT r.SectionIDNum
,r.PeopleIDNum
,r.Completed
,c.CourseID
,s.DistrictIDNum
,s.EndDate
FROM Registration r
,Course c
,Section s
WHERE r.SectionIDNum=s.SectionID
AND c.CourseID=s.CourseIDNum
AND r.Completed='Y'
AND s.EndDate BETWEEN CAST('20120630' AS DATETIME)
AND CAST('20130701'AS DATETIME)
You could also use:
CONVERT(DATETIME,'20130701')