Why insert timestamp but shows date in Snowflake - sql

I have insert a couple of rows into Snowflake table, however it returns only date format.
INSERT INTO usage (Customer_ID,
Movie_Name,
Movie_Genre,
Movie_Length,
Start_Time,
End_Time)
values (1234,
'Shrek',
'Kids',
2.52,
to_timestamp('12-31-2013 13:33','mm-dd-yyyy HH24:MI'),
to_timestamp('12-31-2013 16:04','mm-dd-yyyy HH24:MI')
);
Can someone tell me what's wrong?

SELECT * from values (1234,
'Shrek',
'Kids',
2.52,
to_timestamp('12-31-2013 13:33','mm-dd-yyyy HH24:MI'),
to_timestamp('12-31-2013 16:04','mm-dd-yyyy HH24:MI')
);
gives:
COLUMN1
COLUMN2
COLUMN3
COLUMN4
COLUMN5
COLUMN6
1,234
Shrek
Kids
2.52
2013-12-31 13:33:00.000
2013-12-31 16:04:00.000
so the values block is valid, this implies if you only getting a date, you have a column of type DATE or your default format for display timestamps does not have the time part in it anymore.
select *, system$typeof(Start_Time) from usage;
should show TIMESTAMP

I put date as datetype, should I change to timestamp?
If the column data type is DATE the time component is lost during insertion:
Snowflake supports a single DATE data type for storing dates (with no time elements).
In addition, all accepted TIMESTAMP values are valid inputs for dates; however, the TIME information is truncated.
In order to preserve both date and time the column data type has to be changed to TIMESTAMP.
Sample:
CREATE OR REPLACE TABLE usage(col DATE, col2 TIMESTAMP);
INSERT INTO usage(col, col2)
VALUES (to_timestamp('12-31-2013 13:33','mm-dd-yyyy HH24:MI'),
to_timestamp('12-31-2013 13:33','mm-dd-yyyy HH24:MI'));
SELECT * FROM usage;

Related

Array timestamp not in standard format BigQuery

I created a table in BigQuery and in one of the columns I specified its mode as a REPEATED (array) TIMESTAMP column, that is column4.
CREATE OR REPLACE TABLE
`project.dataset.table` ( column1 string,
column2 TIMESTAMP,
column3 ARRAY<int64>,
column4 ARRAY<TIMESTAMP>)
When I insert data into that table, the column4 converts the CURRENT_TIMESTAMP() into the following format.
INSERT INTO
`project.dataset.table` (column1,
column2,
column3,
column4)
VALUES
("rowtest1", CURRENT_TIMESTAMP(), [5], [CURRENT_TIMESTAMP()])
In the same query I stated the CURRENT_TIMESTAMP() to Column2 and Column4, but for Column4 it changed the format of CURRENT_TIMESTAMP() to 1660318705383274 instead 2022-08-12 15:38:25.383274 UTC .
I want to keep the format as in the Column2 2022-08-12 15:38:25.383274 UTC for both columns, is it possible?
I want to keep the column4 as REPEATED because I will use it as an updated_at field, to avoid redundancy in the table.
BigQuery UI seems to just display a timestamp value in an array as a format of unix timestamp. But internally, it still has a timestamp format in it.
See the query result as a JSON format.
SELECT [CURRENT_TIMESTAMP] ts;
And when you UNNEST an ARRAY<TIMESTAMP>, you can see it as a normal timestamp format like below.
SELECT ts FROM UNNEST([CURRENT_TIMESTAMP]) ts;

Athena Date Partition Without Extra Bits

I have a table with a projected date partition (p_date) that I'm trying to insert values into. When i insert values into this table and specify a string value for the p_date it complains that I am attempting to insert a varchar into a timestamp column (fair). But when I convert the value to a timestamp and do the same insert it adds an unwanted millis value to the end of the timestamp.
-- ERROR varchar cannot be inserted into timestamp
INSERT INTO blah
(p_date)
VALUES
('2021-01-01 00:00:00');
-- Not error. But adds unwanted `.0` to s3 key
INSERT INTO blah
(p_date)
VALUES
(timestamp '2021-01-01 00:00:00');
Here is what that looks like in S3:
How can I insert rows into this table at the correct p_date partition without changing that field to a string or getting extra bits on the end?
Does your partition key have the type TIMESTAMP? In that case Athena will format the values as it formats timestamps. If you want it to format them as dates you can use the DATE type instead.

How to split a datetime column in to two columns of Date and time separately in Oracle SQL?

I have a datetime column.
I want two columns: a date and a time column.
How can I split my column into two?
Use:
a DATE data-type with the time component set to midnight for the date (you can enforce this with a check constraint); and
an INTERVAL DAY(0) TO SECOND data-type for the time component.
CREATE TABLE table_name(
datetime_column DATE,
date_column DATE,
time_column INTERVAL DAY(0) TO SECOND,
CONSTRAINT table_name__date_column__chk CHECK (date_column = TRUNC(date_column))
)
If you want to get the combined date-time then you can easily add the two to get back to a date-time value.
How can I split my column into two?
Assuming you have the columns you can use:
UPDATE table_name
SET date_column = TRUNC(datetime_column),
time_column = (datetime_column - TRUNC(datetime_column)) DAY TO SECOND;
db<>fiddle here
As Gordon commented, there's no time datatype in Oracle.
Though, literally answering what you asked, you can separate date and time and store each of them into their own columns - it's just that these will be VARCHAR2 columns and you can only look at how pretty they are. You can't, for example, do any date arithmetic on them; first you'd have to convert them back to date datatype, so question is what you really want to do with what you get.
Anyway, here you are:
SQL> create table test
2 (datum date,
3 date_only varchar2(10),
4 time_only varchar2(8)
5 );
Table created.
Sample value:
SQL> insert into test (datum) values (sysdate);
1 row created.
Split date to two parts:
SQL> update test set
2 date_only = to_char(datum, 'dd.mm.yyyy'),
3 time_only = to_char(datum, 'hh24:mi:ss');
1 row updated.
What's in there?
SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';
Session altered.
SQL> select * from test;
DATUM DATE_ONLY TIME_ONL
------------------- ---------- --------
05.08.2021 21:05:06 05.08.2021 21:05:06
SQL>
Since there is no specific datatype for time, here my suggestion would be to keep the datetime in main column and add two VIRTUAL COLUMN for date value and time value respectively.
Oracle 11g has introduced a new feature that allows you to create a VIRTUAL COLUMN, an empty column that contains a function upon other table columns (the function itself is stored in the data dictionary).
However, it all depends on what you are going to do with it.
Please elaborate your requirement so that you will get a more specific answer.

Comparing with date in Oracle sql

I have a column 'creation_date' which is of type 'date', when I am querying my table for distinct records based on 'creation_date' I am getting 6 records:
select distinct creation_date from test_table;
output:
06-APR-11
06-APR-11
28-MAR-11
06-APR-11
06-APR-11
18-MAR-11
In this output 6th April is displayed 4 times even when I used distinct in my query. Also when I am trying to find out all records which are matching with creation_date of 6th April 2011 I am not getting any results. Below is my query:
select * from test_table where creation_date = to_date('06-APR-11','DD-MON-YY');
Please help me where I am doing wrong in these two queries.
The problem is twofold. Firstly the dates almost definitely have time-components. to_date('06-MAR-11','DD-MON-YY') is equivalent to 2011/03/06 00:00:00. If you use the TRUNC() function you will be able to see everything for that day:
select *
from test_table
where trunc(creation_date) = to_date('06-MAR-11','DD-MON-YY');
I would not use the MON datetime format model. As I explain here it depends on your region and settings. It's safer to use a numeric month format model instead. Equally, always specify century as part of the year.
where trunc(creation_date) = to_date('06-03-YY11','DD-MM-YYYY');
Your second problem is almost definitely your NLS_DATE_FORMAT; it appears to not take into account the time, hence why you see 4 identical dates. This only governs the manner in which data is displayed not how it is stored.
You can change this using something like:
ALTER SESSION SET NLS_DATE_FORMAT = "DD/MM/YYYY HH24:MI:SS"
If I set up a test environment using the following:
create table test_table ( creation_date date );
insert into test_table values ( sysdate );
insert into test_table values ( sysdate - 0.01 );
alter session set nls_date_format = "YYYY/MM/DD";
You can see the data returned does not include time (though SYSDATE does):
SQL> select * from test_table;
CREATION_D
----------
2013/04/12
2013/04/12
Altering the NLS_DATE_FORMAT and performing the same SELECT, you now get a time component:
SQL> alter session set nls_date_format = "YYYY/MM/DD HH24:MI:SS";
Session altered.
SQL> select * from test_table;
CREATION_DATE
-------------------
2013/04/12 12:48:41
2013/04/12 12:34:17
Lastly, when trying to select today's date alone no rows will be returned:
SQL> select *
2 from test_table
3 where creation_date = to_date('20130412','yyyymmdd');
no rows selected
But, when using TRUNC() to compare on only the date portion of the field you get all your rows again:
SQL> select *
2 from test_table
3 where trunc(creation_date) = to_date('20130412','yyyymmdd');
CREATION_DATE
-------------------
2013/04/12 12:48:41
2013/04/12 12:34:17
To actually answer your second question, if you want unique dates you can re-use the TRUNC() function:
select distinct trunc(creation_date)
from test_table
The DATE datatype stores the year (including the century), the month, the day, the hours, the minutes, and the seconds (after midnight). You must also consider this.

Oracle: Similar to sysdate but returning only time and only date

I understand that Oracle sysdate returns the current date AND time. That's great for timestamp or datetime columns.
Now let's say I have a DATE only column. What keywords should I use on my insert query?
insert into myTable1(myDateOnlyColumn) values(???)
And let's say I have a TIME only column. What keywords should I use on my insert query?
insert into myTable2(myTimeOnlyColumn) values(???)
Thanks!
To remove time from sysdate you can just write TRUNC(sysdate).
For example:
SELECT TRUNC(SYSDATE) "TODAY" FROM DUAL;
will give you:
TODAY
-------------------------
'2012-10-02 00:00:00'
There is no such thing as a DATE only column in Oracle. The DATE datatype stores date and time.
If you only care about the date, you can:
INSERT INTO tbl (dtCol) VALUES (TO_DATE('20110929','YYYYMMDD');
This leaves the time component at 00:00:00. You don't have to display it though.
If you're only interested in the time component, you still have a date stored in the column. You'll just have to handle that on output. For example:
SQL> CREATE TABLE dt (d DATE);
SQL> INSERT INTO dt VALUES (TO_DATE('1:164800','J:HH24MISS'));
1 row inserted
Showing the actual contents of the column reveals a date was inserted:
SQL> SELECT * FROM dt;
D
--------------------
0/0/0000 4:48:00 PM
Selecting only the time component from the column gives you the output you want:
SQL> SELECT TO_CHAR(d, 'HH24:MI:SS') d FROM dt;
D
--------
16:48:00
SQL>
If you think you need only a time column, you'll want to make sure you always insert the same date component.
select sysdate, to_date(to_char(sysdate, 'dd/mm/yyyy'),'dd/mm/yyyy') d
from dual
For whoever is looking for a simple solution for returning only date without time, I found this:
to_date(SYSDATE,'dd/mm/yyyy')
Works like a charm. ;-)