BigQuery TIMESTAMP TO DATETIME - google-bigquery

Conversion rules in Google say that TIMESTAMPS can become DATETIME.
The following code works to turn a TIMESTAMP to a DATE.
SELECT CAST( DATE(CURRENT_TIMESTAMP()) AS DATE)
We can get a DATETIME using this in Standard SQL but we lose the time in the process:
SELECT CAST ( CAST( DATE(CURRENT_TIMESTAMP()) AS DATE) AS DATETIME )
How do we get a TIMESTAMP to become a DATETIME without losing the time (i.e. something like this)?
SELECT CAST( CURRENT_TIMESTAMP() AS DATETIME )
How do we do this in Legacy SQL and Standard SQL on BigQuery?
NOTE: We just discovered our example CAST works on Standard SQL (it appears our query system was using Legacy SQL).

You can simply use CAST(... as DATETIME) as in below example
#standardSQL
WITH `project.dataset.table` AS (
SELECT CURRENT_TIMESTAMP() ts_as_timestamp
)
SELECT ts_as_timestamp, CAST(ts_as_timestamp AS DATETIME) ts_as_datetime
FROM `project.dataset.table`
with result
Row ts_as_timestamp ts_as_datetime
1 2019-06-13 19:22:42.839108 UTC 2019-06-13T19:22:42.839108
For Legacy SQL
#legacySQL
SELECT ts_as_timestamp, CAST(STRING(ts_as_timestamp) AS DATETIME) ts_as_datetime
FROM (SELECT CURRENT_TIMESTAMP() ts_as_timestamp)
with same output

Related

Converting date format number to date and taking difference in SQL

I have a data set as below,
Same is date in "YYYYMMDD" format, I wanted to convert the columns to date format and take the difference between the same.
I used to below code
SELECT to_date(statement_date_key::text, 'yyyymmdd') AS statement_date,
to_date(paid_date_key::text, 'yyyymmdd') AS paid_date,
statement_date - paid_date AS Diff_in_days
FROM Table
WHERE Diff_in_days >= 90
;
Idea is to convert both the columns to dates, take the difference between them and filter cases where difference in days is more than 90.
Later I was informed that server is supported by HiveSQL and does not support of using ":", date time, and temp tables can not be created.
I'm currently stuck on how to go about given the constraints.
Help would be much appreciated.
Sample date for reference is provided in the link
dbfiddle
Hive is a little convoluted in its use of dates. You can use unix_timestamp() and work from there:
SELECT datediff(to_date(unix_timestamp(cast(statement_date_key as varchar(10)), 'yyyyMMdd')),
to_date(unix_timestamp(cast(paid_date_key as varchar(10)), 'yyyyMMdd'))
) as diff_in_days
FROM Table;
Note that you need to use a subquery if you want to use diff_in_days in a where clause.
Also, if you have date keys, then presumably you also have a calendar table, which should make this much simpler.
Hello You Can Use Below Query It Work Well
select * from (
select convert(date, statement_date_key) AS statement_date,
convert(date, paid_date) AS paid_date,
datediff(D, convert(date, statement_date_key), convert(date, paid_date)) as Diff_in_days
from Table
) qry
where Diff_in_days >= 90
Simple way: Function unix_timestamp(string, pattern) converts string in given format to seconds passed from unix epoch, calculate difference in seconds then divide by (60*60*24) to get difference in days.
select * from
(
select t.*,
(unix_timestamp(string(paid_date_key), 'yyyyMMdd') -
unix_timestamp(string(statement_date_key), 'yyyyMMdd'))/86400 as Diff_in_days
from Table t
) t
where Diff_in_days>=90
You may want to add abs() if the difference can be negative.
One more method using regexp_replace:
select * from
(
select t.*,
datediff(date(regexp_replace(string(paid_date_key), '(\\d{4})(\\d{2})(\\d{2})','$1-$2-$3')),
date(regexp_replace(string(statement_date_key), '(\\d{4})(\\d{2})(\\d{2})','$1-$2-$3'))) as Diff_in_days
from Table t
) t
where Diff_in_days>=90

SELECT query with LIKE fails

I'm using a SQL SELECT query to bring back all rows from a specific date.
The column I'm using is called TimeStamp (datetime)
(An example of data from this column = 01/02/2018 07:55:55)
What I would like is to return all rows from a specific date eg 24/06/2019
I have tried
SELECT top 20 TimeStamp
from Report
where TimeStamp = '02/01/2018 07:55:55'
which returns one row (which is correct as there is only one row containing this data)
If I then try
SELECT top 20 TimeStamp
from Report
where TimeStamp LIKE '02/01/2018%'
I get no results, I have also tried escaping the forward slashes
SELECT top 20 TimeStamp
from Report
where TimeStamp = '02\/01\/2018%'
Most databases support a string function called left(). If I assume that your "timestamp" is a string, then:
where left(timestamp, 10) = '01/02/2018'
However, it should be stored as a date or date/time. If so, then you can do:
where timestamp >= '2018-02-01' and
timestamp < '2018-02-02'
Note the use of standard formatted dates (YYYY-MM-DD). That is the way most databases implement date literals.
In SQL Server, you can also use:
where convert(date, timestamp) = '2018-02-01'
Both this and the previous version will use an index on timestamp, so both are reasonable solutions.
this should work
SELECT TimeStamp FROM report where convert(Date, TimeStamp) = '2019-06-24'
or select timestamp from report where timestamp between '2019-06-24' and '2019-06-25'. This will get you everything between 2019-06-24 00:00:00 and 2019-06-25 00:00:00 thus all records with date 2019-06-24
Convert timestamp value to date.
SELECT TimeStamp
FROM report
WHERE CAST(TimeStamp AS DATE) = '2019-06-24'

Convert SQL Server code to Oracle please?

Having a bit of a issue with a SQL conversion from SQL Server to Oracle.
We are passing in a datetime value (in this example just 1900-01-01) and we need to select all rows that have a modified date greater than 2 days before the date passsed in. Here is the SQL syntax that works:
SELECT *
FROM TABLENAME
WHERE CAST(LAST_MODIFIED AS DATE) > CAST(DATEADD(dd, -2, '1990-01-01') AS DATE);
Where LAST_MODIFIED is a column, and the '1900-01-01' is a value being injected to the SQL String in C# prior to it being executed. Before being asked, we prefer not to subtract the 2 days from the date before passing it to the SQL :)
So what we need then is just the above query converted to Oracle syntax... We have tried a couple things and it fails :(
Thanks,
Dave
You can write this in Oracle as:
SELECT *
FROM TABLENAME
WHERE TRUNC(LAST_MODIFIED) > (DATE '1990-01-01') - 2
Notes:
In Oracle, DATE includes a time component, so casting to a date does nothing.
Oracle supports various ways to include a date/time constant. I prefer the keyword DATE with the ISO/ANSI standard date format YYYY-MM-DD.
The - 2 is perhaps more accurately written as - interval '2' day. However, the interval notation is new(ish) to Oracle.
And, it is better in either database to write this without modifying last_modified_date:
SELECT *
FROM TABLENAME
WHERE LAST_MODIFIED >= (DATE '1990-01-01') - 1
Removing the time component is not needed, with the right date comparison.
SELECT *
FROM TABLENAME
WHERE CAST(LAST_MODIFIED AS DATE) > TO_DATE('1990-01-01','YYYY-MM-DD')-2;
SELECT *
FROM TABLENAME
WHERE TRUNC( LAST_MODIFIED ) > TO_DATE( '1990-01-01', 'YYYY-MM-DD' ) - 2;
or, if you pass the value in using the :date_value bind variable:
SELECT *
FROM TABLENAME
WHERE TRUNC( LAST_MODIFIED ) > :date_value - 2;
If the value you are passing in to the query does not have a time component then you can just do:
SELECT *
FROM TABLENAME
WHERE LAST_MODIFIED >= :date_value - 1;

Convert YYYYMMDD String to Date in Impala

I'm using SQL in Impala to write this query. I'm trying to convert a date string, stored in YYYYMMDD format, into a date format for the purposes of running a query like this:
SELECT datadate,
session_info
FROM database
WHERE datadate >= NOW() - INTERVAL 5 DAY
ORDER BY datadate DESC;
Since the >= NOW() - INTERVAL 5 DAY code won't work with the YYYYMMDD string, I'd like to find a way to convert that into a date format that will work with this type of query. My thought is that it should look something like this (based on similar questions about other SQL query editors), but it's not working in Impala:
SELECT datadate,
session_info,
convert(datetime, '20141008', 102) AS session_date
FROM database
WHERE session_date >= NOW() - INTERVAL 5 DAY
ORDER BY session_date DESC;
Anyone know how to do this in Impala?
EDIT:
I finally found a working solution to the problem. None of the attempts using configurations of CAST or CONVERT would work in Impala, but the below query solves the problem and is fully operational, allowing date math to be performed on a column containing string values:
SELECT datadate,
session_info
FROM database
WHERE datadate >= from_unixtime(unix_timestamp(now() - interval 5 days), 'yyyyMMdd')
GROUP BY datadate
ORDER BY datadate DESC;
Native way:
to_timestamp(cast(date_number AS STRING), 'yyyyMMdd')
See Timestamp Literals on [Link Updated 2020-08-24]:
https://docs.cloudera.com/cdp-private-cloud-base/7.1.3/impala-sql-reference/topics/impala-literals.html
You need to add the dashes to your string so Impala will be able to convert it into a date/timestamp. You can do that with something like:
concat_ws('-', substr(datadate,1,4), substr(datadate,5,2), substr(datadate,7) )
which you can use instead of datadate in your expression.
To ignore hour/minute/second... , use from_timestamp, result 2020-01-01.
select from_timestamp(cast('2020-01-01 01:01:01.000000' as TIMESTAMP),'yyyy-MM-dd');

How to select from SQL table WHERE a TIMESTAMP is a specific Date

Im trying to do a query where a TIMESTAMP field is = to a specific date but my query is not working:
The field is type TIMESTAMP(6) which I have only ever worked with DATE / DATETIME fields before. Here is example of a value stored here: 04-OCT-13 12.29.53.000000000 PM
Here is my SELECT statement:
SELECT * FROM SomeTable WHERE timestampField = TO_DATE('2013-10-04','yyyy-mm-dd')
I am retrieving no results and I am assuming it has to do with the fact that its not matching the TIME portion of the timestamp
If you want every record that occurs on a given day then this should work:
SELECT * FROM SomeTable
WHERE timestampField >= TO_TIMESTAMP( '2013-03-04', 'yyyy-mm-dd' )
AND timestampField < TO_TIMESTAMP( '2013-03-05', 'yyyy-mm-dd')
That will be likely to take advantage of an index on timestampField if it exists. Another way would be:
SELECT * FROM SomeTable
WHERE TRUNC(timestampField) = TO_DATE( '2013-03-04', 'yyyy-mm-dd' )
in which case you may want a function-based index on TRUNC(timestampField).
(Note that TRUNC applied to a TIMESTAMP returns a DATE.)