How to cast Timestamp to Date - postgresql

In a view, I'm casting a timestamp without timezone to date.
Looks to me like any of these should work:
Cast("Orders"."OrderDate" as Date),
Date("Orders"."OrderDate"),
"Orders"."OrderDate"::Date,
but they all give the error
cannot change data type of view column "OrderDate" from timestamp without time zone to date
Postgres 11
pgAdmin 4.9

You can't change the type of a column in a view. You will need to drop the view along with all of the objects that depends on that view and create them again.

select date_trunc('day', now());
| date_trunc |
| :--------------------- |
| 2019-08-31 00:00:00+01 |
select date_trunc('day', now())::date;
| date_trunc |
| :--------- |
| 2019-08-31 |
db<>fiddle here

Related

SELECT date and time without second-fractions from unix epoch

The answer to this isn't exactly what I wanted.
I have for example:
select to_timestamp(1476544839);
to_timestamp
------------------------
2016-10-15 16:20:39+01
(1 row)
But I do not want the fractional part of seconds.
Expected:
to_timestamp
------------------------
2016-10-15 16:20:39
PGSQL version:
select version();
version
-------------------------------------------------------------------------------------------------------------------------------------
PostgreSQL 9.6.20 on x86_64-pc-linux-gnu (Ubuntu 9.6.20-1.pgdg18.04+1), compiled by gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0, 64-bit
(1 row)
EDIT
As a follow up to the question, I have this column named timestamp created with time zone.
> \d my_table;
View "postgres.my_table"
Column | Type | Collation | Nullable | Default
------------+--------------------------+-----------+----------+---------
session_id | integer | | |
timestamp | timestamp with time zone | | |
seconds | integer | | |
... ...
And so
SELECT timestamp FROM my_table
timestamp
----------------------------
2016-03-17 08:33:51.842+00
2016-03-17 08:33:51.738+00
2016-03-17 08:33:50.794+00
(3 rows)
It is these fractional part of seconds .842 .739 .794 that I do not want.

Postgresql 12 CAST now() to date not working

I am finding strange why database is having following result:
my1db=# select now()::date;
now
----------------------------
2020-10-08 19:57:24.483647
(1 row)
But here is the result of my other datbase:
my2db=# SELECT now()::date;
now
------------
2020-10-08
(1 row)
My 1st DB is not casting as shown from My 2nd DB
1STDB OS - RHEL 7 dbversion - PostgreSql 12.2
2NDDB OS - RHEL 7 dbversion - PostgreSql 12.1
May I know what am I missing?
It is the reason why I am not getting correct results from my applications
Edit (*removed images):
1STDB
template1=# \dC date
List of casts
Source type | Target type | Function | Implicit?
-----------------------------+-----------------------------+--------------+---------------
date | text | (with inout) | yes
date | timestamp without time zone | timestamp | yes
date | timestamp with time zone | timestamptz | yes
timestamp without time zone | date | date | in assignment
timestamp with time zone | date | date | in assignment
(5 rows)
template1=# select castfunc::regproc from pg_cast where casttarget = 'date'::regtype;
castfunc
------------------------
pg_catalog."timestamp"
pg_catalog."timestamp"
pg_catalog."timestamp"
(3 rows)
template1=# select castfunc::regproc, proname, proowner, prosrc, rolname from pg_cast, pg_proc, pg_authid where casttarget = 'date'::regtype and castfunc = pg_proc.oid and proowner = pg_authid.oid;
castfunc | proname | proowner | prosrc | rolname
------------------------+-----------+----------+-----------------------+---------
pg_catalog."timestamp" | timestamp | 10 | date_timestamp | pgadmin
pg_catalog."timestamp" | timestamp | 10 | timestamptz_timestamp | pgadmin
pg_catalog."timestamp" | timestamp | 10 | timestamp_scale | pgadmin
(3 rows)
2NDDB - cast behaves normally
psql (12.1)
Type "help" for help.
template1=# \dC date
List of casts
Source type | Target type | Function | Implicit?
-----------------------------+-----------------------------+-------------+---------------
date | timestamp without time zone | timestamp | yes
date | timestamp with time zone | timestamptz | yes
timestamp without time zone | date | date | in assignment
timestamp with time zone | date | date | in assignment
(4 rows)
template1=# select castfunc::regproc from pg_cast where casttarget = 'date'::regtype;
castfunc
-----------------
pg_catalog.date
pg_catalog.date
(2 rows)
template1=# select castfunc::regproc, proname, proowner, prosrc, rolname from pg_cast, pg_proc, pg_authid where casttarget = 'date'::regtype and castfunc = pg_proc.oid and proowner = pg_authid.oid;
castfunc | proname | proowner | prosrc | rolname
-----------------+---------+----------+------------------+----------
pg_catalog.date | date | 10 | timestamp_date | postgres
pg_catalog.date | date | 10 | timestamptz_date | postgres
(2 rows)

Outdated row doesn't move out from foreign table partition postgres

I'm trying to learn how sharding is configured in Postgres.
My Postgres setup has a temperature table which has 4 partitions each covering different range of "timestamp" value.
postgres=# \d+ temperature
Partitioned table "public.temperature"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
-----------+-----------------------------+-----------+----------+-----------------------------------------+---------+--------------+-------------
id | bigint | | not null | nextval('temperature_id_seq'::regclass) | plain | |
city_id | integer | | not null | | plain | |
timestamp | timestamp without time zone | | not null | | plain | |
temp | numeric(5,2) | | not null | | main | |
Partition key: RANGE ("timestamp")
Partitions: temperature_201901 FOR VALUES FROM ('2019-01-01 00:00:00') TO ('2019-02-01 00:00:00'),
temperature_201902 FOR VALUES FROM ('2019-02-01 00:00:00') TO ('2019-03-01 00:00:00'),
temperature_201903 FOR VALUES FROM ('2019-03-01 00:00:00') TO ('2019-04-01 00:00:00'),
temperature_201904 FOR VALUES FROM ('2019-04-01 00:00:00') TO ('2019-05-01 00:00:00')
temperature_201904 table, in particular, is a foreign table
postgres=# \d+ temperature_201904
Foreign table "public.temperature_201904"
Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description
-----------+-----------------------------+-----------+----------+-----------------------------------------+-------------+---------+--------------+-------------
id | bigint | | not null | nextval('temperature_id_seq'::regclass) | | plain | |
city_id | integer | | not null | | | plain | |
timestamp | timestamp without time zone | | not null | | | plain | |
temp | numeric(5,2) | | not null | | | main | |
Partition of: temperature FOR VALUES FROM ('2019-04-01 00:00:00') TO ('2019-05-01 00:00:00')
Partition constraint: (("timestamp" IS NOT NULL) AND ("timestamp" >= '2019-04-01 00:00:00'::timestamp without time zone) AND ("timestamp" < '2019-05-01 00:00:00'::timestamp without time zone))
Server: shard02
Insert works as expected. If I insert the following value and check from the remote host shard02, then the value exists. Fantastic!
postgres=# select * from temperature_201904;
id | city_id | timestamp | temp
----+---------+---------------------+-------
1 | 1 | 2019-04-02 00:00:00 | 12.30
(1 row)
However, if I update the timestamp of this row such that it's no longer valid for the range defined for the partition, I'd expect it to get moved out and placed into the correct partition, temperature_201901, but it's not.
postgres=# update temperature set timestamp = '2019-01-04' where id=1;
UPDATE 1
postgres=# select * from temperature_201904 ;
id | city_id | timestamp | temp
----+---------+---------------------+-------
1 | 1 | 2019-01-04 00:00:00 | 12.30
Again, just to reiterate, this table has a range temperature_201904 FOR VALUES FROM ('2019-04-01 00:00:00') TO ('2019-05-01 00:00:00') and is a foreign table.
Feels like I'm missing something here.
Is this an expected behavior? If so, is there a way to configure such that data are automatically moved between nodes as their partition constraints are changed?
Thanks in advance!
postgres=# SELECT version();
version
------------------------------------------------------------------------------------------------------------------
PostgreSQL 12.2 (Debian 12.2-2.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
This seems to be expected. From the docs
While rows can be moved from local partitions to a foreign-table partition (provided the foreign data wrapper supports tuple routing), they cannot be moved from a foreign-table partition to another partition.
Now I would have expected an ERROR rather than silently violating the implied constraint, but I wouldn't expect this to have worked the way to you want it to.

TimescaleDB / PostgreSQL daily maximums with timezone offset

I have problem in sorting & querying data with timezone offset.
I have PostgreSQL + TimescaleDB where I have time series data. Target is to get daily maximums based on local time zone.
My data is in UTC but query needs to be in local timezone as my cumulative counters are resetting in local time.
Target is to have result as in below
id | time | dailymax | name
-------+---------------------+------------------+------------------------
10001 | 2020-01-05 | 0 | Property1
10002 | 2020-01-05 | 20930.3490579984 | Property2
10003 | 2020-01-05 | 28347.1322223556 | Property3
10001 | 2020-01-04 | 57872.3274949118 | Property1
10002 | 2020-01-04 | 101159.612050399 | Property2
10003 | 2020-01-04 | 34113.226521315 | Property3
10001 | 2020-01-03 | 0 | Property1
10002 | 2020-01-03 | 17386.2914203308 | Property2
10003 | 2020-01-03 | 160599.774657208 | Property3
My best guess has been so far query in below, but it gives me also records from wrong days and takes long to execute
SELECT table.id, CAST(datetime AS DATE) AT TIME ZONE 'America/New_York' as time, MAX(value) AS value, map.tagname FROM table
JOIN map ON table.id = map.id
WHERE table.id in(10003,10029,10008,10036,10007) AND datetime AT TIME ZONE 'UTC' >= '2019-12-30T16:09:32.080Z' AND datetime AT TIME ZONE 'UTC' < '2020-01-06T16:09:32.080Z'
GROUP BY table.id, map.tagname, time
ORDER BY time DESC;
With TimescaleDB tried something as in below with bad luck as well
SELECT table.id, to_char(time_bucket('24 hours', datetime) at time zone 'utc', 'YYYY-MM-DD"T"HH24:MI:SS"Z"') as time, max(value) as value, map.name FROM
table JOIN map ON table.id = map.id
WHERE table.id in(10001,10002) AND datetime >= '2020-01-01' AND datetime < '2020-01-10'
GROUP BY time, table.id, map.name ORDER BY time DESC`;

Get specific time period from a list of epoch in Postgres

I have the following table with epoch timestamps in Postgres. I would like to select the timestamps where the time is from 20:00 to 21:00 in PST. I have tried the following partially but I can't seem to extract both hour and minutes.
SELECT timestamp from table where extract(‘hour’ from to_timestamp(created_at) at time zone ‘America/Los_angeles’) > 20
| created_at |
| 1526528788 |
| 1526442388 |
| 1526309188 |
| 1526359588 |
| 1526532388 |
| 1526489188 |
Expected result:
| created_at |
| 1526528788 |
| 1526442388 |
Any help would be greatly appreciated.
Why do you write America/Los Angeles when you mean PST? They are (sometimes) different.
Does that solve your problem:
... WHERE extract(hour FROM
to_timestamp(1526309188) AT TIME ZONE 'PST'
) BETWEEN 20 AND 21;