How to compare string field as Date in postgresql? - postgresql

I have a string field in a table whose value is date format like: 2020-12-08T18:06:55.132Z or 2020-12-08T18:06:55.132+11:00.
How can I search this field based on date? Like select * from my_table where timestamp > '2020-12-08T00:00:00'.

You can try something like:
SELECT *
FROM my_table
WHERE to_timestamp(timestamp,'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') > '2020-12-08T00:00:00'
EDIT:
Something even easier, which doesn't rely on your timestamp format:
SELECT *
FROM my_table
WHERE timestamp::timestamp > '2020-12-08T00:00:00'

Related

How to query by time in postgresql

device_id
device_created_at
10e7983e-6a7b-443f-b0fe-d5e6485a502c
2022-08-10 20:55:16.695
i have a table where my date/time is of form: 2022-08-10 20:55:16.695 This is a timestampped object. I tried the following query but didn't return any rows:
select * from device where to_char(device_created_at,'YYYY-MM-DD HH24:MI:SS.FFF') = '2022-08-10 20:55:16.695'
The type of device_created_at is "timestamp without time zone"
How do i query based on timestamp in postgressql?
Try comparing timestamp values in place of strings:
SELECT *
FROM device
WHERE device_created_at = CAST('2022-08-10 20:55:16.695' AS TIMESTAMP)
Check the demo here.

How to query from the result of a changed column of a table in postgresql

So I have a string time column in a table and now I want to change that time to date time type and then query data for selected dates.
Is there a direct way to do so? One way I could think of is
1) add a new column
2) insert values into it with converted date
3) Query using the new column
Here I am stuck with the 2nd step with INSERT so need help with that
ALTER TABLE "nds".”unacast_sample_august_2018"
ADD COLUMN new_date timestamp
-- Need correction in select statement that I don't understand
INSERT INTO "nds".”unacast_sample_august_2018” (new_date)
(SELECT new_date from_iso8601_date(substr(timestamp,1,10))
Could some one help me with correction and if possible a better way of doing it?
Tried other way to do in single step but gives error as Column does not exist new_date
SELECT *
FROM (SELECT from_iso8601_date(substr(timestamp,1,10)) FROM "db_name"."table_name") AS new_date
WHERE new_date > from_iso8601('2018-08-26') limit 10;
AND
SELECT new_date = (SELECT from_iso8601_date(substr(timestamp,1,10)))
FROM "db_name"."table_name"
WHERE new_date > from_iso8601('2018-08-26') limit 10;
Could someone correct these queries?
You don't need those steps, just use USING CAST clause on your ALTER TABLE:
CREATE TABLE foobar (my_timestamp) AS
VALUES ('2018-09-20 00:00:00');
ALTER TABLE foobar
ALTER COLUMN my_timestamp TYPE timestamp USING CAST(my_timestamp AS TIMESTAMP);
If your string timestamps are in a correct format this should be enough.
Solved as follows:
select *
from
(
SELECT from_iso8601_date(substr(timestamp,1,10)) as day,*
FROM "db"."table"
)
WHERE day > date_parse('2018-08-26', '%Y-%m-%d')
limit 10

tsql convert string into date when possible

I've got a column to import into an Azure SQL DB that is supposed to be made of dates only but of course contains errors.
In TSQL I would like to do something like: convert to date if it's possible otherwise null.
Does anyone know a statement to test the convertibility of a string into a date?
use TryCast or Isdate
select
try_Cast('test' as date)
select try_Cast('4' as date)
select case when ISDATE('test')=1 then cast('test' as date) else null end
TryCast will fail if the expression is not in expected format ..ie.,if the explicit conversion of expression is not permitted
select
try_cast( 4 as xml)
select try_Cast(4 as date)
You could use TRY_PARSE:
Returns the result of an expression, translated to the requested data type, or null if the cast fails. Use TRY_PARSE only for converting from string to date/time and number types.
SELECT TRY_PARSE('20129901' AS DATE)
-- NULL
Additionaly you could add culture:
SELECT TRY_PARSE('10/25/2015' AS DATE USING 'en-US')
And importing:
INSERT INTO target_table(date_column, ...)
SELECT TRY_PARSE(date_string_column AS DATE) ...
FROM source_table
...

Select from JSONB field with WHERE clause

Just installed 9.4 and trying to use JSONB field type.
I've made a table with jsonb field and able to select from it:
select statistics->'statistics'->'all_trades'->'all'->'all_trades_perc_profit' as profitable_perc FROM trade_statistics
Works fine.
Now I want to filter results based on field value:
select statistics->'statistics'->'all_trades'->'all'->'all_trades_perc_profit' as profitable_perc FROM trade_statistics WHERE profitable_perc > 1
//There is no "profitable_perc" column
Does not work.
If I try to convert result to double, does not work either.
select cast(statistics->'statistics'->'all_trades'->'all'->'all_trades_perc_profit' as double precision) as profitable_perc FROM trade_statistics
//cant convert jsonb into double precision
How should I use select results in WHERE clause in case of jsonb?
Three corrections have to be made:
Wrap the the query in a subquery - you cannot reference the SELECT list aliases in WHERE clause
Use the ->> operator to get the value as text
Cast the text value as integer so you can make the comparison
SELECT *
FROM (
SELECT (statistics->'statistics'->'all_trades'->'all'->>'all_trades_perc_profit')::integer as profitable_perc
FROM trade_statistics
) sq1
WHERE profitable_perc > 1

Extract year from date within WHERE clause

I need to include EXTRACT() function within WHERE clause as follow:
SELECT * FROM my_table WHERE EXTRACT(YEAR FROM date) = '2014';
I get a message like this:
pg_catalog.date_part(unknown, text) doesn't exist**
SQL State 42883
Here is my_table content (gid INTEGER, date DATE):
gid | date
-------+-------------
1 | 2014-12-12
2 | 2014-12-08
3 | 2013-17-15
I have to do it this way because the query is sent from a form on a website that includes a 'Year' field where users enter the year on a 4-digits basis.
The problem is that your column is of data type text, while EXTRACT() only works for date / time types.
You should convert your column to the appropriate data type.
ALTER TABLE my_table ALTER COLUMN date TYPE date;
That's smaller (4 bytes instead of 11 for the text), faster and cleaner (disallows illegal dates and most typos).
If you have non-standard format add a USING clause with a conversion expression. Example:
Alter character field to date
Also, for your queries to be fast with a plain index on date you should rather use sargable predicates. Like:
SELECT * FROM my_table
WHERE date >= '2014-01-01'
AND date < '2015-01-01';
Or, to go with your 4-digit input for the year:
SELECT * FROM my_table
WHERE date >= to_date('2014', 'YYYY')
AND date < to_date('2015', 'YYYY');
You could also be more explicit:
to_date('2014' || '0101', 'YYYYMMNDD')
Both produce the same date '2014-01-01'.
Aside: date is a reserved word in standard SQL and a basic type name in Postgres. Don't use it as identifier.
This happens because the column has a text or varchar type, as opposed to date or timestamp. This is easily reproducible:
SELECT 1 WHERE extract(year from '2014-01-01'::text)='2014';
yields this error:
ERROR: function pg_catalog.date_part(unknown, text) does not exist
LINE 1: SELECT 1 WHERE extract(year from '2014-01-01'::text)='2014';
^ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
extract or is underlying function date_part does not exist for text-like datatypes, but they're not needed anyway. Extracting the year from this date format is equivalent to getting the 4 first characters, so your query would be:
SELECT * FROM my_table WHERE left(date,4)='2014';