How to change string to timestamp? - google-bigquery

I have a timestamp data that still in STRING type like below:
+-----------------------------+
| created_at |
+-----------------------------+
| 2019-09-05T07:44:32.117283Z |
+-----------------------------+
| 2019-09-05T08:44:32.117213D |
+-----------------------------+
| 2019-09-06T08:44:32.117283A |
+-----------------------------+
| 2019-09-21T09:42:32.117223T |
+-----------------------------+
| 2019-10-21T10:21:14.1174dwC |
+-----------------------------+
How can I change it to ISO Format like "2020-09-05 07:44:32 UTC"?
Thanks in advance

You can use PARSE_TIMESTAMP('%FT%T', SPLIT(created_at, '.')[OFFSET(0)]) or PARSE_TIMESTAMP('%FT%T', SUBSTR(created_at, 1, 19)) - whatever you like better
You can test, play with above using sample data from your question as in below example
#standardSQL
WITH `project.dataset.table` AS (
SELECT '2019-09-05T07:44:32.117283Z' created_at UNION ALL
SELECT '2019-09-05T08:44:32.117213D' UNION ALL
SELECT '2019-09-06T08:44:32.117283A' UNION ALL
SELECT '2019-09-21T09:42:32.117223T' UNION ALL
SELECT '2019-10-21T10:21:14.1174dwC'
)
SELECT PARSE_TIMESTAMP('%FT%T', SPLIT(created_at, '.')[OFFSET(0)])
FROM `project.dataset.table`
with output
Row f0_
1 2019-09-05 07:44:32 UTC
2 2019-09-05 08:44:32 UTC
3 2019-09-06 08:44:32 UTC
4 2019-09-21 09:42:32 UTC
5 2019-10-21 10:21:14 UTC

Related

Update date on datetime field without losing the format

I have a table with two columns: M_OP_DATE (of type DATE) and M__DT_UTC_DATE (of type TIMESTAMP(3)).
The table contains data as follows:
+---------------------+---------------------+
| M_OP_DATE | M__DT_UTC_DATE |
+---------------------+---------------------+
| 2018-09-03 00:00:00 | 2018-09-25 20:14:57 |
| 2018-08-31 00:00:00 | 2018-09-25 20:15:05 |
| 2018-08-31 00:00:00 | 2018-09-25 20:15:05 |
+---------------------+---------------------+
I would like to copy the date from M_OP_DATE, without touching the time, in the field M__DT_UTC_DATE.
I have searched on SO and found this answer which looked pretty much what I needed to do: already answered question.
I have hence adapted that answer to my data and come up with something like this:
update FXKAUD_H_DBF set M__DT_UTC_DATE = to_date(substr(M_OP_DATE, 0, 9) || ' ' || to_char(M__DT_UTC_DATE, 'HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS')
However, the result was not the expected one:
+---------------------+---------------------+
| M_OP_DATE | M__DT_UTC_DATE |
+---------------------+---------------------+
| 2018-08-29 00:00:00 | 2029-08-18 14:47:07 |
+---------------------+---------------------+
As you can see, the year is 2029 and the day is 18. It basically swapped the two digits of the day with the two last digits of the year.
When I try just to select what's inside substr(M_OP_DATE, 0, 9), I can see that it shows me the result differently than what I see in the table with a simple select:
select substr(M_OP_DATE, 0, 9) from FXKAUD_H_DBF
+-----------------------+
| SUBSTR(M_OP_DATE,0,9) |
+-----------------------+
| 29-AUG-18 |
+-----------------------+
... and it's when I try to format this string to date in format YYYY-MM-DD that the issue comes up:
select to_date(substr(M_OP_DATE, 0, 9), 'YYYY-MM-DD') from FXKAUD_H_DBF
| TO_DATE(SUBSTR(M_OP_DATE,0,9),'YYYY-MM-DD') |
+---------------------------------------------+
| 0029-08-18 00:00:00 |
+---------------------------------------------+
Can anyone please guide me through the good approach?
Sorry for not providing with a SQLfiddle, but the site is down for me (I'll check later if I can add it to the question).
One method is:
select M_OP_DATE + (M__DT_UTC_DATE - trunc(M__DT_UTC_DATE))
Or:
select M__DT_UTC_DATE - (trunc(M__DT_UTC_DATE) - M_OP_DATE
The query will be:
update FXKAUD_H_DBF set M__DT_UTC_DATE = M__DT_UTC_DATE - (trunc(M__DT_UTC_DATE) - M_OP_DATE)

Netezza time formatting

Need to convert timestamps with 1/1000 second resolution to 1/100 resolution. I could possibly use to_char(timestamp, text) formatting function for this purpose, however need help with text to be used. Postgres way of doing this is here.
input table (note - the timestamp here is stored as varchar)
+-------------------------+
| ms1000_val |
+-------------------------+
| 2017/02/20 08:27:17.899 |
| 2017/02/20 08:23:43.894 |
| 2017/02/20 08:24:41.894 |
| 2017/02/20 08:28:09.899 |
+-------------------------+
output table
+------------------------+
| ms100_val |
+------------------------+
| 2017/02/20 08:27:17.89 |
| 2017/02/20 08:23:43.89 |
| 2017/02/20 08:24:41.89 |
| 2017/02/20 08:28:09.89 |
+------------------------+
Try this
select cast(to_char(sub.field,'YYYY-MM-DD HH24:MI:SS') as timestamp)
+ interval '10 millisecond' * (cast(to_char(sub.field,'MS') as integer)/10) as converted_value
from (
select to_timestamp('2017/02/20 08:27:17.899','YYYY/MM/DD HH24:MI:SS.MS') as field
union
select to_timestamp('2017/02/20 08:23:43.894','YYYY/MM/DD HH24:MI:SS.MS')
union
select to_timestamp('2017/02/20 08:24:41.894','YYYY/MM/DD HH24:MI:SS.MS')
union
select to_timestamp('2017/02/20 08:28:09.899','YYYY/MM/DD HH24:MI:SS.MS')
) sub

Why cast as timestamp give out two different result

I have a hive table with two rows like this:
0: jdbc:hive2://localhost:10000/default> select * from t2;
+-----+--------+
| id | value |
+-----+--------+
| 10 | 100 |
| 11 | 101 |
+-----+--------+
2 rows selected (1.116 seconds)
but when I issue a query :
select cast(1 as timestamp) from t2;
it gives out unconsistent result, can anyone tell me the reason ?
0: jdbc:hive2://localhost:10000/default> select cast(1 as timestamp) from t2;
+--------------------------+
| _c0 |
+--------------------------+
| 1970-01-01 07:00:00.001 |
| 1970-01-01 07:00:00.001 |
+--------------------------+
2 rows selected (0.913 seconds)
0: jdbc:hive2://localhost:10000/default> select cast(1 as timestamp) from t2;
+--------------------------+
| _c0 |
+--------------------------+
| 1970-01-01 08:00:00.001 |
| 1970-01-01 07:00:00.001 |
+--------------------------+
2 rows selected (1.637 seconds)
I can't reproduce your problem, which Hive version are you using? Hive had a bug with timestamp and bigint (see https://issues.apache.org/jira/browse/HIVE-3454), but it doesn't explain your problem. For example Hive 0.14 gives different results for
SELECT (cast 1 as timestamp), cast(cast(1 as double) as timestamp) from my_table limit 5;

Select row with timestamp nearest to, but not later than, now

Using Postgres 9.4, I am trying to select a single row from from a table that contains data nearest to, but not before, the current system time. The datetime colum is a timestamp without time zone data type, and the data is in the same timezone as the server. The table structure is:
uid | datetime | date | day | time | predictionft | predictioncm | highlow
-----+---------------------+------------+-----+----------+--------------+--------------+---------
1 | 2015-12-31 03:21:00 | 2015/12/31 | Thu | 03:21 AM | 5.3 | 162 | H
2 | 2015-12-31 09:24:00 | 2015/12/31 | Thu | 09:24 AM | 2.4 | 73 | L
3 | 2015-12-31 14:33:00 | 2015/12/31 | Thu | 02:33 PM | 4.4 | 134 | H
4 | 2015-12-31 21:04:00 | 2015/12/31 | Thu | 09:04 PM | 1.1 | 34 | L
Query speed is not a worry since the table contains ~1500 rows.
For clarity, if the current server time was 2015-12-31 14:00:00, the row returned should be 3 rather than 2.
EDIT:
The solution, based on the accepted answer below, was:
select *
from myTable
where datetime =
(select min(datetime)
from myTable
where datetime > now());
EDIT 2: Clarified question.
You can also use this. This will be faster. But it wont make much difference if you have few rows.
select * from table1
where datetime >= current_timestamp
order by datetime
limit 1
SQLFiddle Demo
The general idea follows. You can adjust it for postgresql.
select fields
from yourTable
where datetimeField =
(select min(datetimeField)
from yourTable
where datetimeField > current_timestamp)
Another approach other than the answers given is to use a window function first_value
select id, first_value(dt) over (order by dt)
from test
where dt >= current_timestamp
limit 1
See it working here: http://sqlfiddle.com/#!15/0031c/12

How to check date in postgresql

my table name is tbl1. The fileds are id,name,txdate.
| ID | NAME | TXDATE |
| 1 | RAJ | 1-1-2013 |
| 2 | RAVI | |
| 3 | PRABHU | 25-3-2013 |
| 4 | SAT | |
Now i want to use select query for check txdate < 2-2-2013 in which rows have txdate not empty and the select also retrun which rows have txdate empty.
The Result is like this
| ID | NAME | TXDATE |
| 1 | RAJ | 1-1-2013 |
| 2 | RAVI | |
| 4 | SAT | |
Any feasible solution is there?.
With out using union it is possible?.
Assuming that the TXDATE is of data type DATE then you can use WHERE "TXDATE" < '2013-2-2' OR "TXDATE" IS NULL. Something like:
SELECT *
FROM table1
WHERE "TXDATE" < '2013-2-2'
OR "TXDATE" IS NULL;
See it in action:
SQL Fiddle Demo
I don't now what database your are using and what data type the TXDATE is.
I just tried on my postgreSQL 9.2, with a field "timestamp without time zone".
I have three rows in the table , like:
ac_device_name | ac_last_heartbeat_time
----------------+-------------------------
Nest-Test1 |
Nest-Test3 |
Nest-Test2 | 2013-04-10 15:06:18.287
Then use below statement
select ac_device_name,ac_last_heartbeat_time
from at_device
where ac_last_heartbeat_time<'2013-04-11';
It is ok to return only one record:
ac_device_name | ac_last_heartbeat_time
----------------+-------------------------
Nest-Test2 | 2013-04-10 15:06:18.287
I think you can try statement like:
select * from tbl1 where TXDATE<'2-2-2013' and TXDATE is not NULL
this statement also works in my environment.