Typecasting datetime differences - sql

We use firebird as a local testing database and most of our clients use SQL Server or Oracle.
This works in MS SQL Server, but not in Firebird. (haven't tested it n Oracle yet)
CONVERT(char(8),MAX(p.end_Time)-MIN (p.start_Time),8) as duration
is there a way to acoomplish this same thing for (Firebird, Oracle, and MS Sql Server)?
thanks

For Firebird you need to use DATEDIFF to obtain a difference between two timestamps (datetimes). This BTW is similar to the SQL Server DATEDIFF. If you then want to cast it to char, you can use CAST, eg CAST(DATEDIFF(DAY, MAX(p.end_Time), MIN(p.start_Time)) AS CHAR(8)) should do the trick (or you can simply do CAST(MAX(p.end_Time) - MIN (p.start_Time) AS CHAR(8)) as timestamps are subtractable.
I just noticed though that the option you specify in your CONVERT will convert to hh:mi:ss. There is no such option in Firebird. If you need to convert specifically to hh:mi:ss, you might want to look at UDF libraries like FreeAdhocUDF (specifically F_SECONDS2PERIOD) or rFunc UDF. If all else fails, you could write your own UDF.

there is no CONVERT on firebird.
Use CAST:
select cast(MAX(p.end_Time) as varchar(50)) and so on...

On Oracle (Oracle 8i, Oracle 9i, Oracle 10g, Oracle 11g), you can use to_char function:
select to_char( value, [ format_mask ], [ nls_language ] ) ....
Example:
SELECT TO_CHAR ( SYSDATE - TO_DATE ( '18-10-2012', 'dd-mm-yyyy' ), '9,999.99' ) as duration FROM DUAL;
Here is the link for Oracle/PLSQL: To_Char Function

Related

[SQL]Removing day in yyyy/mm/dd datetime format in sql

I'm using PostgreSQL, but this question is for any modern dbms
I want to basically convert a datetime column which has yyyy/mm/dd into just yyyy/mm
I tried getting months and year separately and using Concat, but the problem is the month comes as a single digit integers for values < 10 and that messes up ordering
select *,
concat(date_part('year' , date_old), '/', date_part('month' , date_old)) as date_new
from table
date _old
date_new
2010-01-20
2010-1
2010-01-22
2010-1
2010-11-22
2010-11
You can use to_char()
to_char(date_old, 'yyyy/mm')
If you want to display your date in the format YYYY-MM then
In PostgreSQL (db<>fiddle) and Oracle (db<>fiddle), use TO_CHAR:
SELECT TO_CHAR(date_old, 'YYYY/MM') FROM table_name;
In MySQL (db<>fiddle), use DATE_FORMAT:
SELECT DATE_FORMAT(date_old, '%Y/%m') FROM table_name;
In SQL Server (db<>fiddle), use CONVERT or, if you are using SQL Server 12 or later, FORMAT:
SELECT CONVERT(varchar(7), date_old, 111) FROM table_name;
SELECT FORMAT(date_old,'yyyy/MM') FROM table_name;
Don't do this.
If you're able to use the date_part() function, what you have is not actually formatted as the yyyy/mm/dd value you say it is. Instead, it's a binary value that's not human-readable, and what you see is a convenience shown you by your tooling.
You should leave this binary value in place!
If you convert to yyyy/mm, you will lose the ability to directly call functions like date_part(), and you will lose the ability to index the column properly.
What you'll have left is a varchar column that only pretends to be a date value. Schemas that do this are considered BROKEN.

Get the number of days between two dates

I'm working on JupyterLab(SQL) and I want to get the difference of days between two columns.
The values of the columns are in the format YYYYMMDD but they aren't integers
How can I transform the columns to dates and then get the differences of days.
I'm not totally sure about JupyterLab, but in SQL Server you can use DATEDIFF() to calculate this. For example:
SELECT DATEDIFF(day, '2017/08/25', '2011/08/25') AS DateDiff;
See also:
https://www.w3schools.com/sql/func_sqlserver_datediff.asp
You did not mention the dbms so i am answering for oracle and postgres. You can use above answers but i like to convert them explicitly befor calculating difference.
so here is for
oracle -
TO_DATE('20170103','YYYYMMDD') - TO_DATE('20200103','YYYYMMDD')
postgres
EXTRACT(DAY FROM TO_TIMESTAMP('20160101', 'YYYYMMDD')-TO_TIMESTAMP('20150301', 'YYYYMMDD')
JupyterLab(SQL) supports SQLite, PostgreSQL, and MySQL databases:
MySQL:
SELECT DATEDIFF("20201005", "20201001");
PostgreSQL:
SELECT DATE_PART('day', AGE('20201005', '20201001'));

Convert 10JAN2000:00:00:00 to DATETIME in SQL

I have been provided with a file whereby the dates are in the aforementioned format.
I have never seen this format before so am I going to have to separate the data out and convert each section or is this actually a known format?
Cheers
Most databases have some sort of to_date() or parse_date() functionality . . . except SQL Server.
If you are using SQL Server, then this should work:
select cast(stuff('10JAN2000:00:00:00', 10, 1, ' ') as datetime)
select to_char(to_date('10JAN2000:00:00:00', 'ddmonyyyy:hh24:mi:ss'),'yyyy-mm-dd : hh:mm:ss') from dual;
as suggested by others, knowing which database changes the answer. SQL Server isn't keen on supporting date parse function unlike oracle, please read through below threads, might help with better understanding-
Sql Server string to date conversion
to_date in SQL Server 2005
In oracle of course, we can do something like this-
select to_date('10JAN2000:00:00:00', 'ddmonyyyy:hh24:mi:ss') from dual;
or
select to_timestamp('10JAN2000:00:00:00', 'ddmonyyyy:hh24:mi:ss') from dual;

Errors while trying to cast/convert VARCHAR to DATETIME in ANSI SQL

I have a column in a table where timestamps have been stored in VARCHAR format, but I need to compare these against a column of DATETIME values from another table to find time intervals, so I want to either cast or convert the VARCHAR timestamps to DATETIME. However, both casting and converting are giving me problems.
The format of the VARCHAR timestamp looks like this: "29/07/2012 01:53:36 +12".
Using the query:
SELECT CAST(event_timestamp AS datetime) FROM the_table
produces ERROR: date/time field value out of range: "29/07/2012 01:53:36 +12".
Using the query:
SELECT CONVERT(datetime, event_timestamp, 131) from the_table;
produces
ERROR: syntax error at or near ","
LINE 1: select CONVERT(datetime, event_timestamp, 131) from the_tab...
^ (note: this is pointing at the first comma).
The error with CONVERT actually happens even if you use a generic function such as getdate() for the data source. This db uses ANSI SQL-92 (or so I'm told). Could anyone please help me out with this?
This seems really painful, but the following should work:
select dateadd(hh, cast(right(tv, 3) as int),
CONVERT(datetime, left(tv, 10), 103)+CONVERT(datetime, substring(tv, 12, 8), 108)
)
from (select '29/07/2012 01:53:36 +12' as tv) t
I've never added datetime's before, but this just worked on SQL Server 2008.
Why can't SQL Server just support a flexible notation built around yyyy, mm, mmm, dd and so on?
The actual database is Aster Data, which is based on Postgres (as are most recent database engines). In this database, you would use to_timestamp(). See the documentation here http://www.postgresql.org/docs/8.2/static/functions-formatting.html. The call would be something like:
to_timestamp(val, 'MM/DD/YYYY HH:MI:SS tz') -- not sure if this gets the +12
There are no ANSI functions for date conversion, so each database does its own. Even string functions vary among databases (substr? substring? charindex? instr? location?), so there is no ANSI way to do this.
You are using the wrong syntax, try:
CONVERT(varchar(X), datetimeValue, 131)
Where X is the total number of characters desired.
You will then be able to search for a match with datetimeValue and event_timestamp, assuming each value share the same structure. This will allow you to match string against string.
If I'm not mistaken the standard (ANSI SQL) CAST operator always expect time/date/timstamp literals in ISO format ('YYYY-MM-DD')
But according to the manual for Teradata V12 (can't test it), the format of the CAST operator is
CAST(character_expression AS TIMESTAMP timestamp_data_attribute)
with date_data_attribute being a character value plus an optional FORMAT specifier.
So in your case this would probably be:
cast(event_timestamp AS TIMESTAMP FORMAT 'MM/DD/YYYY HH:MI:SS Z');
I'm not entirely sure about the format definition though. You'll probably need to adjust that
Btw: CONVERT isn't a standard SQL function. It's SQL Server specific.

ANSI standard of UNIX_TIMESTAMP()

UNIX_TIMESTAMP() isn't an ANSI standard keyword but an addition to the MySQL syntax. However, since I'm supporting multiple DB's, is there an ANSI standard way to write UNIX_TIMESTAMP();
Thanks
As far as I know, no.
Every database handles this differently.
For example, in Oracle, you have to manually generate the timestamp with something like:
SELECT (sysdateColumn - to_date('01-JAN-1970','DD-MON-YYYY')) * (86400) AS alias FROM tableName;
In MSSSQL:
SELECT DATEADD(s, yourDateColumn, '19700101') AS alias FROM tableName
In PGSQL:
SELECT date_part('epoch', timestampColumn) AS alias FROM tableName
Edit: as AlexKuznetsov pointed out, there are two totally different usages of MySQL's UNIX_TIMESTAMP() function. I assumed the latter, UNIX_TIMESTAMP(date) (for native format to epoch conversion) for the above answer.
You failed to define UNIX_TIMESTAMP
If the following is true:
UNIX_TIMESTAMP(date) returns the value of the argument as seconds since '1970-01-01 00:00:00'
then use DATEDIFF function