Conversion between timestamp to milliseconds in DB2 - db2

I have a column of datatype timestamp. Now I need to convert it to MiiliSeconds and put in another column. How can I do that.
the input is of the format 2011-10-04 13:54:50.455227 and the output needs to be 1317900719

There's a function called timestampdiff. Using it against January 1st 1970 would work otherwise but the function gives approximate results. If you want accuracy you will want to calculate the correct answer with something like
create function ts2millis(t timestamp)
returns bigint
return (
(
(bigint(year(t-1970))*bigint(31556926000))+
(bigint(month(t))*bigint(2629743000))+
(bigint(day(t))*bigint(86400000))+
(bigint(hour(t))*bigint(3600000))+
(bigint(minute(t))*bigint(60000))+
(bigint(second(t))*bigint(1000))+
(bigint(microsecond(t))/bigint(1000))
)
)
#

Your requested output is not miliseconds, but the equivalent to CLib localtime(), here's how to do it:
SELECT
86400*
(
DAYS(TIMESTAMP(v_timestamp))
-
DAYS(TIMESTAMP('1970-01-01-00:00:00'))
)
+
MIDNIGHT_SECONDS(timestamp(v_timestamp))
FROM
SYSIBM.SYSDUMMY1;
where v_timestamp is the variable or column to be calculated.

Related

In Amazon Redshift though I have specified service_date column as Date datatype but when I am taking date in IN operator it working with quotes only

select *
from nsclc_thought_spot
where patientid = 11000001
and service_date in ('2019-07-08', '2019-07-10')
order by patientid, service_date
is returning the results properly
But this is not working as expected:
select *
from nsclc_thought_spot
where patientid = 11000001
and service_date in (2019-07-08, 2019-07-10)
order by patientid, service_date
This query is not returning results.
If I have defined service_date column as date, then why do I have to pass the values in quotes inside IN operator in redshift?
Because 2019-07-08 means the integer 2019 minus the integer 7 minus the integer 8 which equals the integer 2004. Without quotes in SQL numbers are seen as numeric values. To be interpreted as something else you need to quote them (which is a text value) and then they need to be cast to the data type needed. In this case '2019-07-08' is a text value but Redshift will implicitly cast this to a date to make the comparison to the column data "service_date".
If you want to do this explicitly you can add the casting to the values - ... service_date IN ('2019-07-08'::date,'2019-07-10'::date) ... - which might make things clearer for you.

Convert ABAP date to HANA date returning NULL if empty

My task is to convert a ABAP style date (i.e. 2017-11-20 which is represented as string "20171120") to a HANA date via sql script. This can easily be done by:
select to_date('20171120','YYYYMMDD') from dummy;
But there is another requirement: if the abap date is initial (value '00000000') the database shall store a null value. I have found a working solution: I replace the potential initial date '00000000' with 'Z' and trim the string to null if only 'Z' is found:
select to_date(trim(leading 'Z' from replace('00000000','00000000','Z')),'YYYYMMDD') from dummy;
-- result: null
select to_date(trim(leading 'Z' from replace('20171120','00000000','Z')),'YYYYMMDD') from dummy;
-- result: 2017-11-20
But this looks like a dirty hack. Has anybody an idea for a more elegant solution?
As explained in my presentation Innovation with SAP HANA - What are my options all that string manipulation is really not necessary.
Instead, use the appropriate conversion functions when dealing with ABAP date and time data. In this case, DATS_TO_DATE is the correct function.
with in_dates as
( select '20171120' as in_date from dummy
union all select '00000000' as in_date from dummy)
select
dats_to_date(in_date)
, in_date
from in_dates;
|DATS_TO_DATE(IN_DATE) |IN_DATE
-------------------------+---------
|2017-11-20 |20171120
|? |00000000
The ? here is the output representation for NULL.
DATS_TO_DATE does not return NULL if the given date is initial (0000-00-00), but a special date value (-1-12-31 to be precise).
To receive a NULL value in this case, as you requested, use the following statement:
NULLIF( DATS_TO_DATE(?), DATS_TO_DATE('00000000'))
e. g.:
INSERT INTO null_test VALUES (NULLIF( DATS_TO_DATE('00000000'), DATS_TO_DATE('00000000')));
=> returns NULL
INSERT INTO null_test VALUES (NULLIF( DATS_TO_DATE('20171224'), DATS_TO_DATE('00000000')));
=> returns 2017-12-24
As there are no tedious string operations involved, this statement should yield good performance.

RIGHT Function in UPDATE Statement w/ Integer Field

I am attempting to run a simple UPDATE script on an integer field, whereby the trailing 2 numbers are "kept", and the leading numbers are removed. For example, "0440" would be updated as "40." I can get the desired data in a SELECT statement, such as
SELECT RIGHT(field_name::varchar, 2)
FROM table_name;
However, I run into an error when I try to use this same functionality in an UPDATE script, such as:
UPDATE schema_name.table_name
SET field_name = RIGHT(field_name::varchar, 2);
The error I receive reads:
column . . . is of type integer but expression is of type text . . .
HINT: You will need to rewrite or cast the expression
You're casting the integer to varchar but you're not casting the result back to integer.
UPDATE schema_name.table_name
SET field_name = RIGHT(field_name::TEXT, 2)::INTEGER;
The error is quite straight forward - right returns textual data, which you cannot assign to an integer column. You could, however, explicitly cast it back:
UPDATE schema_name.table_name
SET field_name = RIGHT(field_name::varchar, 2)::int;
1 is a digit (or a number - or a string), '123' is a number (or a string).
Your example 0440 does not make sense for an integer value, since leading (insignificant) 0 are not stored.
Strictly speaking data type integer is no good to store the "trailing 2 numbers" - meaning digits - since 00 and 0 both result in the same integer value 0. But I don't think that's what you meant.
For operating on the numeric value, don't use string functions (which requires casting back and forth. The modulo operator % does what you need, exactly: field_name%100. So:
UPDATE schema_name.table_name
SET field_name = field_name%100
WHERE field_name > 99; -- to avoid empty updates

How to extract timestamp from mongodb objectid in postgres

In MongoDB you can retrieve the date from an ObjectId using the getTimestamp() function. How can I retrieve the date from a MongoDB ObjectId using Postgresql (e.g., in the case where such an ObjectId is stored in a Postgres database)?
Example input:
507c7f79bcf86cd7994f6c0e
Wanted output:
2012-10-15T21:26:17Z
In Mongodb documentation the Objectid is formed with a timestamp as the first 4 bytes, but this is represented in hexidecimal. Assuming that hexidecimal value is stored as a string in PostgreSQL, then the following query will extract just the first 8 characters of that objectid, convert that to an integer (which is seconds from 1970-01-01) then convert that integer to a timestamp. For example:
SELECT TO_TIMESTAMP(int_val) ts_val
FROM (
SELECT ('x' || lpad(left(objectid,8), 8, '0'))::bit(32)::int AS int_val
FROM (
VALUES ('507c7f79bcf86cd7994f6c0e')
) AS t1(objectid)
) AS t2
;
Converting a hexadecimal string to integer is discussed here:
Convert hex in text representation to decimal number
The first answer is quite excellent. This one expands the answer by making a reusable function out of it.
create function extractMongoTimestamp(text) RETURNS TIMESTAMP WITH TIME ZONE
as
'SELECT TO_TIMESTAMP(int_val) ts_val
FROM (
SELECT (''x'' || lpad(left(objectid,8), 8, ''0''))::bit(32)::int AS int_val
FROM (
VALUES ($1)
) AS t1(objectid)
) AS t2'
language sql
immutable
RETURNS null on null input;
Use it in your query:
select extractMongoTimestamp('507c7f79bcf86cd7994f6c0e');

function to_char(unknown, unknown) is not unique

When running the following the query.select * from surgicals where to_char(dt_surgery ,'DD-MM-YYYY' ) = to_char('12-02-2012','DD-MM-YYYY');
the error coming as 'SQL state 42725: ERROR: function to_char(unknown, unknown) is not unique'
How to run above select query?
You probably mean to_char('12-02-2012'::date, 'DD-MM-YYYY'). to_char cannot convert a plain string to string. Still, it does not seem to make sense, you need one of these two, depending on the format of your date constant (which cannot be determined from the actual example date you provided):
select * from surgicals where to_char(dt_surgery ,'DD-MM-YYYY' ) = '12-02-2012';
select * from surgicals where to_char(dt_surgery ,'MM-DD-YYYY' ) = '12-02-2012';
The wrongness here is that you're doing string comparison of dates. Use date/time math, which can take into account fun things like time zones etc. and still get it right.
Maybe this is what you need:
SELECT *
FROM surgicals
WHERE date_trunc('day', dt_surgery) = '2012-02-12'
;