SQLite DateTime query - why it doesnt work? - sql

I have below table in my SQLite DB.:
CREATE TABLE [TICK] (
TS DATETIME NOT NULL,
PRICE DECIMAL(10,3) NOT NULL
);
Im trying to filter out given date & time range - for example:
SELECT * FROM TICK t WHERE ts between '2017-01-25 21:44:13' AND '2017-03-21 16:35:14'
But this returns 1st record with ts=2017-01-26 08:00:00, while '2017-01-25 21:45:12' is expected
I can improve that by casting ts as DateTime:
SELECT * FROM TICK t WHERE datetime( ts) between '2017-01-25 21:44:13' AND '2017-03-21 16:35:14'
But I dont understand why I need to do that (if TS column is already DateTime Type) ?
Also performance of such query is 10x slower than 1st one
Please advise how to deal with TimeStamps in Sqlite... (I havent such issues in other DB engines)
Example data:
TS |PRICE |
--------------------+--------+
2017-01-30 08:00:00|2293.598|
2017-01-30 08:01:00| 2287.14|
2017-01-30 08:02:00|2287.194|
2017-01-30 08:03:00|2287.335|
2017-01-30 08:04:00| 2287.23|
2017-01-30 08:05:00|2287.078|
2017-01-30 08:06:00|2287.156|
2017-01-30 08:07:00|2287.063|
2017-01-30 08:08:00|2286.782|

Summarizing this up for others' benefit
Ive learnt that:
SQLlite does not really have DateTime type,
but DDL allows to create such field type
Ive overlooked I had 2 spaces between date and time - what caused issue
As Sqlite doesn't have such type you cannot count on it it will be controlling what you put into such field
All credits to #forpas

Related

How do I convert a text column to a timestamp column in PostgreSQL?

I have a text column "A" in table X and I want to convert it to a timestamp column without a timezone in table Y.
How can I perform this conversion in PostgreSQL?
Input: Table X
A (text)
2006-08-30 21:30:00
21:30:00
Desired Output: Table Y
Output (timestamp)
2006-08-30 21:30:00
21:30:00
The TIME data type by itself is pretty much useless, which occurred first 23:00:00 or 01:00:00, without the date part you cannot tell. However you can get it what you want by applying cast twice: first string to timestamp then timestamp to time. Using Postgres cast operator (::) that becomes: (see demo)
select ts_as_string::timestamp::time from table_x;
NOTES: First, heed the comment by #FrankHeikens and use the proper data type for your timestamp and not text. You can virtually guarantee that at some point someone will insert an invalid value in that column (like 'N/A' perhaps) and Postgres will not stop it after all you declared it valid. Second, Postgres 9.5 reached end-of-life in Feb 2021. You should update your version.

How to get different date formats in Oracle DB from a select query existing in a table?

In my Oracle DB, I have a date field called HIGH_DATE. The format for some entries is "27-SEP-12" (DD-MON-YY) and for some entries it is "27-09-12" (DD-MM-YY).
Can someone help me in framing a select query through which I can get dates in either formats??
If you have a DATE column then it does not have any format; it is stored internally as 7-bytes (century, year-of-century, month, day, hour, minute, second) and it is only when the user interface being used to access the database returns data to the user that it then gets formatted (and all the dates will be implicitly converted to strings with a consistent format).
I'm going to assume that when you say:
I have a date field called "HIGH_DATE"
What you actually mean is: "I have a column with a VARCHAR2 data-type where I store date values".
If that is the case then all you need to do is:
SELECT TO_DATE( high_date, 'DD-MM-RR' ) AS high_date
FROM table_name;
Oracle's string-to-date conversion rules will match additionally the MON format model if you use the MM format model and don't specify an exact match using the FX format model.
If you have the test data:
CREATE TABLE table_name ( high_date ) AS
SELECT '23-09-20' FROM DUAL UNION ALL
SELECT '15-AUG-99' FROM DUAL;
Then the above query will output (depending on your NLS_DATE_FORMAT):
| HIGH_DATE |
| :------------------ |
| 2020-09-23T00:00:00 |
| 1999-08-15T00:00:00 |
db<>fiddle here
However, the best solution is going to be to stop storing the values as strings and to store them (without a format) as a date.

Replace the time as 0's in datetime column

Experts,
I need to convert the time value as 0's in a datetime column leaving behind 00:00:00.000.
Sample data:
2019-04-17 08:47:51.433
2019-04-17 00:00:00.000
Kindly suggest a key code.
Thanks in advance!
As you appear to want to keep a time of 00:00:00.000 you could use
SELECT DATE_FORMAT('2019-04-17 08:47:51.433' , '%Y-%m-%d 00:00:00.000');
RESULT
2019-04-17 00:00:00.000
To trim the time part, you can just use MySQL date function DATE():
Demo on DB Fiddle:
select DATE('2019-04-17 08:47:51.433')
| DATE('2019-04-17 08:47:51.433') |
| :------------------------------ |
| 2019-04-17 |
I will assume that you really only want to view your datetime data this way. If so, then you should use DATE_FORMAT with a mask containing only the date portion:
SELECT
dt AS datetime,
DATE_FORMAT(dt, '%Y-%m-%d') AS dateonly
FROM yourTable;
Unless you are certain that you would never need the time information, it makes no sense to throw that away.

CAST as TIMESTAMP not working for some string formats

I have a field in a BigQuery table that is a STRING but is actually a timestamp, of the format "2019-06-14T11:31:07". So I am using CAST(sign_up_date AS TIMESTAMP) to convert to a usable TIMESTAMP.
This works perfectly in Legacy SQL, however, in Standard SQL, it brings up errors when the STRING is of the format "2019-06-14T09:09" (on the exact minute, missing ":00") or "2019-05-25T05:31:22.7263555" (as sometimes they come through with decimal seconds).
Any idea on how I can get it to work in Standard SQL? Obviously I could just use Legacy SQL, but I want to write in Standard as there are other functionns that work better in that one.
Thanks,
Benji
Below is example for BigQuery Standard SQL
#standardSQL
WITH `project.dataset.table` AS (
SELECT "2019-06-14T11:31:07" sign_up_date UNION ALL
SELECT "2019-05-25T05:31:22.7263555" UNION ALL
SELECT "2019-06-14T09:09"
)
SELECT sign_up_date,
COALESCE(
SAFE.PARSE_TIMESTAMP('%FT%R', sign_up_date),
SAFE.PARSE_TIMESTAMP('%FT%R:%E*S', sign_up_date)
) AS sign_up_date_as_timestamp
FROM `project.dataset.table`
with result
Row sign_up_date sign_up_date_as_timestamp
1 2019-06-14T11:31:07 2019-06-14 11:31:07 UTC
2 2019-05-25T05:31:22.7263555 2019-05-25 05:31:22.726355 UTC
3 2019-06-14T09:09 2019-06-14 09:09:00 UTC
As you can see this will cover all three patters you presented in your question.
If you will find more - you can add respective SAFE.PARSE_TIMESTAMP inside COALESCE

Showing month and year

I have a query that results in a timestamp value along with certain other calculations.
The result looks something like below -
City DateTime Value
London 2009-01-01 00:00:00.000000 22
New York 2010-01-01 00:00:00.000000 33
... ... ...
Is there any way to obtain the dateTime column with month and year - something like Jan-2009 and Jan-2010 instead of entire timestamp. I don't want to use the case statement.
t=# select now(),to_char(now(),'Mon-YYYY');
now | to_char
-------------------------------+----------
2017-09-20 07:49:34.360483+00 | Sep-2017
(1 row)
https://www.postgresql.org/docs/current/static/functions-formatting.html
to_char(timestamp, text)
and
https://www.postgresql.org/docs/current/static/functions-formatting.html#FUNCTIONS-FORMATTING-DATETIME-TABLE
for formats
the postgresql data type formating function to_char can solve this problem. It takes 2 arguments, a timestamp and a template pattern string, and return a date string according to the provided pattern. see Postgresql documentation for the complete pattern list.
You can try something like the following:
select city, to_char(your_date_field, 'Mon-YYYY'), value from your_table