Insert data in a column geometry on redshift - amazon-redshift

I created this table on a database in redshift; and try to insert data. Do you know how to insert the point coordinate into the column geometry ?
CREATE TABLE airports_data (
airport_code character(3),
airport_name character varying,
city character varying,
coordinates geometry,
timezone timestamp with time zone
);
INSERT INTO airports_data(airport_code,airport_name,city,coordinates,timezone)
VALUES ('YKS','Yakutsk Airport','129.77099609375, 62.093299865722656', 'AsiaYakutsk');
I had an error when trying to make this insert.
Query ELAPSED TIME: 13 m 05 s ERROR: Compass I/O exception: Invalid
hexadecimal character(s) found

In Redshift, make your longitude and latitude values into a geometry object. Use:
ST_Point(longitude, latitude) -- for an XY point
ST_GeomFromText('LINESTRING(4 5,6 7)') -- for other geometries
You're missing city in your INSERT VALUES and 'AsiaYakutsk' is not a valid datetime value - see https://docs.aws.amazon.com/redshift/latest/dg/r_Datetime_types.html#r_Datetime_types-timestamptz
Ignoring your timezone column and adding city into values, use this:
INSERT INTO airports_data(airport_code,airport_name,city,coordinates)
VALUES ('YKS','Yakutsk Airport','Yakutsk',ST_Point(129.77099609375, 62.093299865722656));

Related

How to find average of the column

Thanks in advance.
How to find avg when the column datatype is character varying in PostgreSQL.
here growth and literacy are character-varying.
Select avg(cast(GROWTH as float)) from census2;
I have created a table name called census2
create table census2
(
District VARCHAR(200)
, STATE VARCHAR(250)
, Growth NUMERIC
, Sex_Ratio NUMERIC
, Literacy NUMERIC
);
After successful creation while adding CSV file it is displaying errors as
ERROR: invalid input syntax for type numeric: "Growth"
CONTEXT: COPY census2, line 503, column growth: "Growth"

How to calculate the difference between two timestamptz in Postgres

I have a table and I want to calculate the difference (in time) between two columns of my table.
My columns are: scheduled_arrival_time(timestamptz), scheduled_departure_time(timestamptz) and I want to get the difference of them as "scheduled_duration"
(scheduled_duration = scheduled_arrival_time - scheduled_departure_time)
I tried this:
scheduled_departure_time TIMESTAMPTZ NOT NULL,
scheduled_arrival_time TIMESTAMPTZ NOT NULL,
scheduled_duration numeric(4,2) NOT NULL
generated always as
( extract(epoch from (scheduled_arrival_time - scheduled_departure_time))/3600 )
stored
but I got the error when I tried to insert data:
ERROR: cannot insert a non-DEFAULT value into column "scheduled_duration" DETAIL: Column "scheduled_duration" is a generated column. SQL state: 428C9
You can do this with for excample:
SELECT
EXTRACT(EPOCH FROM '2022-06-16 15:00:00.00000'::TIMESTAMP - '2022-06-15 15:00:00.00000'::TIMESTAMP)
You get the difference in seconds.

Why does ST_Transform fail when transforming to 4326?

I have a postgis table with some data which looks like this:
distance
id
nr
X
Y
description
strecke
point
gsal_strecke
rikz
gsal_km_anf_p
gsal_km_end_p
gsal_geo_compound
rk
kilometer
basepoint
2.088918198132633
9105
1
7.59833269418573
50.3171094720011
valide with result
3507
POINT (3400245.168425543 5576618.697108934)
3507
2.0
123905.310
123945.537
LINESTRING (3400253.52199817 5576605.02429315, 3400251.48999817 5576609.59229315, 3400247.37399817 5576618.87129315, 3400243.28599817 5576628.16129316, 3400239.24399817 5576637.47229316, 3400237.27599817 5576642.06929316)
1
123.92110139140328
POINT (3400247.0804134225 5576619.538465925)
4.601389947759623
9106
611171
8.83478109
54.7923646
crash
1201
POINT (3489442.4653895213 6073687.653162317)
1201
0.0
162291.691
162329.922
LINESTRING (3489446.77287361 6073662.83069441, 3489447.226 6073701.05844041)
1
162.31646103819043
POINT (3489447.066456252 6073687.598624319)
This table holds the end result of some calculations. In short what happens is, that a collection of points is inserted into the database and if they are within a certain perimter of a given rail, a basepoint to that rail is calculated. This calculation takes place in SRID 5683
The data is fetched by a Service, which returns them as geojson. According to the specification, geoJSON works best when used with WGS84 coordinates.
So when fetching the data, I have to transform the coordinates.
The query I use looks like this:
select *, ST_X(ST_Transform(point, 4326)) as x, ST_Y(ST_Transform(point, 4326)) as y from bp40.bp40_punktlage;
The first of these two example rows yields the following result:
distance
id
nr
X
Y
Objektbezeichnung
strecke
punkt
gsal_strecke
rikz
gsal_km_anf_p
gsal_km_end_p
gsal_geo_compound
rk
kilometer
fusspunkt
x
y
2.088918198132633
9105
1
7.59833269418573
50.3171094720011
valide mit ergebnis
3507
POINT (3400245.168425543 5576618.697108934)
3507
2.0
123905.310
123945.537
LINESTRING (3400253.52199817 5576605.02429315, 3400251.48999817 5576609.59229315, 3400247.37399817 5576618.87129315, 3400243.28599817 5576628.16129316, 3400239.24399817 5576637.47229316, 3400237.27599817 5576642.06929316)
1
123.92110139140328
POINT (3400247.0804134225 5576619.538465925)
7.598332691520598
50.317109473199004
Now for some reason I cannot explain, the second row just crashes yielding the follow error message:
SQL Error [XX000]: ERROR: transform: Invalid argument (22)
According to the postgres documentation
This is a internal error, which does not really help me understand what is wrong here.
I have checked the geometry for validity (st_isvalid) and both rows contain valid geometry.
Also the initial X,Y coordinates are valid and pinpoint the location I want them to be in.
EDIT 1
Out of curiosity i tried the following queries:
select st_transform(point,5682) from bp40_punktlage
--works just fine with both rows
select st_transform(st_transform(punkt, 5682),4326) from bp40_punktlage
-- crashes with the same error
PostgreSQL 13.4, compiled by Visual C++ build 1914, 64-bit
Postgis Version : 3.1 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
Edit 2
As requestet here is the CREATE TABLE statement:
CREATE TABLE bp40.bp40_punktlage (
distance float8 NULL,
id int4 NULL,
nr varchar NULL,
"X" float8 NULL,
"Y" float8 NULL,
"description" varchar NULL,
strecke varchar NULL,
point geometry NULL,
gsal_strecke varchar(4) NULL,
rikz float8 NULL,
gsal_km_anf_p numeric(19, 3) NULL,
gsal_km_end_p numeric(19, 3) NULL,
gsal_geo_compound geometry NULL,
rk int8 NULL,
kilometer float8 NULL,
basepoint geometry NULL
);
Inserts are a bit more complicated, since the data goes through several tables and processing steps until it arrives at the table shown in this post. I will try to add them over the course of the day.
Edit 3
The geometries are valid.
st_srid() return 5863 for both points, as expected. I tried transforming them into 5862 just for the sake of trying. But it fails when transforming to 4326, no matter from which SRID i start

insert a CSV file with polygons into PostgreSQL

I've got a CSV file including 3 columns named boundaries,category and city.
the data in every cell,below the column "boundaries" is comprised of something like this:
{"coordinates"=>[[[-79.86938774585724, 43.206149439482836], [-79.87618446350098, 43.19090988330086], [-79.88626956939697, 43.19328385965552], [-79.88325476646423, 43.200029828720744], [-79.8932647705078, 43.20258723593195], [-79.88930583000183, 43.211150250203886], [-79.86938774585724, 43.206149439482836]]], "type"=>"Polygon"}
how can I create a table with a proper data type for column "boundaries"?
The data you have specified is in JSON format, so you could either store the boundaries data as a jsonb table column.
e.g: CREATE TABLE cities ( city varchar, category varchar, boundaries jsonb)
The alternative is to parse the JSON and store the coordinates in a PostgreSQL ARRAY column: something like:
CREATE TABLE cities (
city varchar,
category varchar,
boundary_coords point ARRAY,
boundary_type varchar
)

How to insert values into Postgresql column with datatype as double precision

When I am trying to insert a date with timestamp to my postgresql table, I am getting the below error:
ERROR: invalid input syntax for type double precision: "2011-05-31 02:20:30"
The query is below. Here the ID field is a text and the REPORTED_DATE field is a double precision.
insert into my_table ("ID", "REPORTED_DATE") values('ID8033','2011-05-31 02:20:30');
How do I need to change the query to be able to insert it ? Or do I need to change the datatype of the REPORTED_FIELD column accordingly ?
You need to change the datatype of REPORTED_FIELD, use timestamp, or change the string to get the time (seconds, milliseconds) of date and change the field to integer.
double precision is a floating-point number: https://www.postgresql.org/docs/9.5/static/datatype.html.
You are looking for timestamp: https://www.postgresql.org/docs/9.5/static/datatype-datetime.html