updating a varchar column with multiple select stmts - db2

I have to update a VARCHAR column of a table by concatenating values from SELECT queries from another table. I have build a query like
UPDATE url SET VALUE = (SELECT id FROM ids WHERE identifier='site')':'(SELECT id FROM cids WHERE identifier='cid')
WHERE name='SToken:CToken'
AND tokenvalue LIKE (SELECT id FROM ids WHERE identifier='site');
Here value is VARCHAR.
How should I do this?

Related

How to do a select inside an insert using Postgresql?

I am a beginner in postgresql and databases in general. I have a table with a column product_id. Some of the values in that column are null. I need to change those null values to the values from another table.
I want to do something like this:
insert into a(product_id) (select product_id from b where product_name='foo') where product_id = null;
I realize that this syntax doesn't work but I just need help figuring it out.
Assuming your table name is "a" and you have some null product_id, but the othe colums does contain data.
So you need to UPDATE, not to INSERT.
Your Query will be something like this :
Update a
set product_id = select product_id from b where b.product_name = 'foo'
Where product_id is null
be sure that your sub query (select ..from b) return a unique value.
Try below
INSERT INTO a (product_id)
select product_id from b where product_name='foo';
your where condition is wrong after the) bracket I.e. where product_id = null;

Can I refer to data in jsonb table if no matching field in cross join table

I have json data in table that I use to insert new data into final table as follows
CREATE TABLE musicbrainz.acoustid_track (
id int NOT NULL,
created timestamp with time zone DEFAULT current_timestamp,
gid uuid NOT NULL,
new_id varchar(30)
);
CREATE TABLE musicbrainz.acoustid_track_json (
data jsonb
);
......
tables loaded
......
The json column data is visible in the query and you can refer to it in the WHERE clause, e.g.:
insert into musicbrainz.acoustid_track
select id, created, gid, new_id
from musicbrainz.acoustid_track_json
cross join jsonb_populate_record(null::musicbrainz.acoustid_track, data);
and this works except acoustid_track_json can contains new records or replacement records, and this is detemrined by if they have an updated field
e.g
New record
{"id":67028798,"gid":"18575a2d-bc9c-48c0-b5d7-f815b97421ed","created":"2020-02-03T00:02:11.315629+00:00"}
Updated record
{"id":66277512,"gid":"a31e1ecc-af48-4b8f-ba65-de5187a5c9a7","new_id":65603612,"created":"2019-11-17T12:37:49.81505+00:00","updated":"2020-02-03T13:12:58.043985+00:00"}
but I cant seem to modify INSERT to refer to updated field, possibly because no updated field in the final table, how do I do this.
The json column data is visible in the query and you can refer to it in the WHERE clause, e.g.:
insert into musicbrainz.acoustid_track
select id, created, gid, new_id
from musicbrainz.acoustid_track_json
cross join jsonb_populate_record(null::musicbrainz.acoustid_track, data)
where data->'updated' is null;

Output Inserted.id equivalent in Postgres

I am new to PostgreSQL and trying to convert mssql scripts to Postgres.
For Merge statement, we can use insert on conflict update or do nothing but am using the below statement, not sure whether it is the correct way.
MSSQL code:
Declare #tab2(New_Id int not null, Old_Id int not null)
MERGE Tab1 as Target
USING (select * from Tab1
WHERE ColumnId = #ID) as Source on 0 = 1
when not matched by Target then
INSERT
(ColumnId
,Col1
,Col2
,Col3
)
VALUES (Source.ColumnId
,Source.Col1
,Source.Col2
,Source.Col3
)
OUTPUT INSERTED.Id, Source.Id into #tab2(New_Id, Old_Id);
Postgres Code:
Create temp table tab2(New_Id int not null, Old_Id int not null)
With source as( select * from Tab1
WHERE ColumnId = ID)
Insert into Tab1(ColumnId
,Col1
,Col2
,Col3
)
select Source.ColumnId
,Source.Col1
,Source.Col2
,Source.Col3
from source
My query is how to convert OUTPUT INSERTED.Id in postgres.I need this id to insert records in another table (lets say as child tables based on Inserted values in Tab1)
In PostgreSQL's INSERT statements you can choose what the query should return. From the docs on INSERT:
The optional RETURNING clause causes INSERT to compute and return value(s) based on each row actually inserted (or updated, if an ON CONFLICT DO UPDATE clause was used). This is primarily useful for obtaining values that were supplied by defaults, such as a serial sequence number. However, any expression using the table's columns is allowed. The syntax of the RETURNING list is identical to that of the output list of SELECT. Only rows that were successfully inserted or updated will be returned.
Example (shortened form of your query):
WITH [...] INSERT INTO Tab1 ([...]) SELECT [...] FROM [...] RETURNING Tab1.id

How to insert and then update returned Id from insert query as returning id in a single command in postgres?

I have a demo table
CREATE TABLE items (
id SERIAL primary key,
user_id integer,
name character varying,
created timestamp with time zone default now()
);
And I want a single query to run and first insert data, then return primary key using returning id and then update the same table with the returned id.
INSERT INTO items (name) values ('pen') RETURNING id as idd
update items set user_id=(select idd) where id=(select idd)
but the above command doesn't work and throws syntax error.
Any help will be appriciated.
You can do that right within the INSERT statement:
INSERT INTO items
(name, user_id)
values
('pen', currval(pg_get_serial_sequence('items','id')));
Online example
You can try this way also :
create temp table insert_item as
with insert_item_cte as (
INSERT INTO items (name)
values ('pen') returning id
)
select id from insert_item_cte;
update items set user_id = items.id
from insert_item ii
where ii.id = items.id;
Online Demo

Ambiguous column in PostgreSQL UPSERT (writeable CTE) using one table to update another

I have a table called users_import into which I am parsing and importing a CSV file. Using that table I want to UPDATE my users table if the user already exists, or INSERT if it does not already exist. (This is actually a very simplified example of something much more complicated I'm trying to do.)
I am trying to do something very similar to this:
https://stackoverflow.com/a/8702291/912717
Here are the table definitions and query:
CREATE TABLE users (
id INTEGER NOT NULL UNIQUE PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE users_import (
id INTEGER NOT NULL UNIQUE PRIMARY KEY,
name TEXT NOT NULL
);
WITH upsert AS (
UPDATE users AS u
SET
name = i.name
FROM users_import AS i
WHERE u.id = i.id
RETURNING *
)
INSERT INTO users (name)
SELECT id, name
FROM users_import
WHERE NOT EXISTS (SELECT 1 FROM upsert WHERE upsert.id = users_import.id);
That query gives this error:
psql:test.sql:23: ERROR: column reference "id" is ambiguous
LINE 11: WHERE NOT EXISTS (SELECT 1 FROM upsert WHERE upsert.id = us...
^
Why is id ambiguous and what is causing it?
The RETURNING * in the WITH upsert... clause has all columns from users and all columns from the joined table users_import. So the result has two columns named id and two columns named name, hence the ambiguity when refering to upsert.id.
To avoid that, use RETURNING u.id if you don't need the rest of the columns.