Adding values to a newly inserted column in an existing table in PostgreSQL 9.3 - postgresql

created a table named "collegetable":
create table collegetable (stid integer primary key not null,stname
varchar(50),department varchar(10),dateofjoin date);
provided values for each column:collegetable data
inserted a new column in it named "cgpa" and tried to add values for this column in one shot using the code:
WITH col(stid, cgpa) as
( VALUES((1121,8.01),
(1131,7.12),
(1141,9.86))
)
UPDATE collegetable as colldata
SET cgpa = col.cgpa
FROM col
WHERE colldata.stid = col.stid;
and got error :
ERROR:operator does not exist:integer=record
LINE9:where colldata.stid=col.stid;
HINT:No operator matches the given name and arguement type.you might need to add explicit type casts.
pls help in solving.thanks in advance.

The with clause only defines the names of the columns, not the data types:
with col (stid, cgpa) as (
...
)
update ...;
For details see the tutorial and the full reference

Related

Fetch rows from postgres table which contains a specific id in jsonb[] column

I have a details table with adeet column defined as jsonb[]
a sample value stored in adeet column is as below image
Sample data stored in DB :
I want to return the rows which satisfies id=26088 i.e row 1 and 3
I have tried array operations and json operations but it does'nt work as required. Any pointers
Obviously the type of the column adeet is not of type JSON/JSONB, but maybe VARCHAR and we should fix the format so as to convert into a JSONB type. I used replace() and r/ltrim() funcitons for this conversion, and preferred to derive an array in order to use jsonb_array_elements() function :
WITH t(jobid,adeet) AS
(
SELECT jobid, replace(replace(replace(adeet,'\',''),'"{','{'),'}"','}')
FROM tab
), t2 AS
(
SELECT jobid, ('['||rtrim(ltrim(adeet,'{'), '}')||']')::jsonb as adeet
FROM t
)
SELECT t.*
FROM t2 t
CROSS JOIN jsonb_array_elements(adeet) j
WHERE (j.value ->> 'id')::int = 26088
Demo
You want to combine JSONB's <# operator with the generic-array ANY construct.
select * from foobar where '{"id":26088}' <# ANY (adeet);

How to insert new parameter into column in PostgreSql

I have a table called device, the table has a column called devicMeta. The deviceMeta looks like
{"id":"1234567890", "firmware":"1.001","hardware":"1.0"}
I want to insert a new parameter into column 'deviceMeta', for example "company":'ABC', the expected result is
{"id":"1234567890","firmware":"1.001","hardware":"1.0","company":'ABC'}
How can I do this using PostgreSql's UPDATE command
UPDATE "device"
?
WHERE "id" = '1234567890'
Assuming that column is defined as jsonb (which it should be) you can simply concatenate the new key/value pair:
update device
set devicemeta = devicemeta || '{"company": "ABC"}'
where id = 123456789;

Update column with multiple values Postgres

Sample data:
I am trying update a column with values from multiple columns in another table if two columns match.
Consider the following query:
UPDATE application_table
SET asset_list = asset_table.asset_name
FROM asset_table
WHERE application_table.application_name = asset_table.applications;
My table structure is:
application_table:
"asset_list"; "text[]"
"application_name"; "character varying"
asset_table:
"asset_name"; "character varying"
"applications"; "character varying"
I get the following error:
ERROR: column "asset_list" is of type text[] but expression is of type character varying
Line 12 SET asset_list = asset_table.asset_name
What you need to do is aggregate the asset_name per applications value and set asset_list to that aggregated value.
Problem is you can't do something like
UPDATE ..
SET asset_list = ARRAY_AGG(asset_name)
FROM ...
because aggregate functions are not allowed in updates like that.
So here's two other ways to do it:
UPDATE app_table
SET asset_list = _asset_list
FROM (
SELECT applications, ARRAY_AGG(asset_name ORDER BY asset_name) AS _asset_list
FROM asset_table
GROUP BY applications
) AS a
WHERE app_name = applications;
https://www.db-fiddle.com/f/pKB5k6Lexwzqv6ZbCCdJay/0
This first builds a result set of distinct application names and an array of all the asset_names for each of the app names. Then it updates the table as usual with that array value.
Another way is:
UPDATE app_table
SET asset_list = (SELECT ARRAY_AGG(asset_name ORDER BY asset_name)
FROM asset_table
WHERE applications = app_name)
;
https://www.db-fiddle.com/f/8oVWsubXW93n142gtZYLXB/0
This will update every record in app_table, and calculates the array value on the fly for every record.

Postgres Update Using Select Passing In Parent Variable

I need to update a few thousand rows in my Postgres table using the result of a array_agg and spatial lookup.
The query needs to take the geometry of the parent table, and return an array of the matching row IDs in the other table. It may return no IDs or potentially 2-3 IDs.
I've tried to use an UPDATE FROM but I can't seem to pass into the subquery the parent table geom column for the SELECT. I can't see any way of doing a JOIN between the 2 tables.
Here is what I currently have:
UPDATE lrc_wales_data.records
SET lrc_array = subquery.lrc_array
FROM (
SELECT array_agg(wales_lrcs.gid) AS lrc_array
FROM layers.wales_lrcs
WHERE st_dwithin(records.geom_poly, wales_lrcs.geom, 0)
) AS subquery
WHERE records.lrc = 'nrw';
The error I get is:
ERROR: invalid reference to FROM-clause entry for table "records"
LINE 7: WHERE st_dwithin(records.geom_poly, wales_lrcs.geom, 0)
Is this even possible?
Many thanks,
Steve
Realised there was no need to use SET FROM. I could just use a sub query directly in the SET:
UPDATE lrc_wales_data.records
SET lrc_array = (
SELECT array_agg(wales_lrcs.gid) AS lrc
FROM layers.wales_lrcs
WHERE st_dwithin(records.geom_poly, wales_lrcs.geom, 0)
)
WHERE records.lrc = 'nrw';

Postgres query error

I have a query in postgres
insert into c_d (select * from cd where ak = '22019763');
And I get the following error
ERROR: column "region" is of type integer but expression is of type character varying
HINT: You will need to rewrite or cast the expression.
An INSERT INTO table1 SELECT * FROM table2 depends entirely on order of the columns, which is part of the table definition. It will line each column of table1 up with the column of table2 with the same order value, regardless of names.
The problem you have here is whatever column from cd with the same order value as c_d of the table "region" has an incompatible type, and an implicit typecast is not available to clear the confusion.
INSERT INTO SELECT * statements are stylistically bad form unless the two tables are defined, and will forever be defined, exactly the same way. All it takes is for a single extra column to get added to cd, and you'll start getting errors about extraneous extra columns.
If it is at all possible, what I would suggest is explicitly calling out the columns within the SELECT statement. You can call a function to change type within each of the column references (or you could define a new type cast to do this implicitly -- see CREATE CAST), and you can use AS to set the column label to match that of your target column.
If you can't do this for some reason, indicate that in your question.
Check out the PostgreSQL insert documentation. The syntax is:
INSERT INTO table [ ( column [, ...] ) ]
{ DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) | query }
which here would look something like:
INSERT INTO c_d (column1, column2...) select * from cd where ak = '22019763'
This is the syntax you want to use when inserting values from one table to another where the column types and order are not exactly the same.