Teradata MERGE with DELETE and INSERT - syntax? - merge

I have been trying to find the correct syntax for the following case (if it is possible?):
MERGE INTO TAB_A tgt
USING TAB_B src ON (src.F1 = tgt.F1 AND src.F2 = tgt.F2
WHEN MATCHED THEN DELETE
ELSE INSERT (tgt.*) VALUES (src.*)
Background: the temp table contains a fix for the target table, as in it contains two types of rows:
the incorrect rows that are to be removed (they match with rows in the target table), and the 'corrected' row that should be inserted (it replaces all the 'delete' rows).
So essentially: remove anything that matches;
insert anything that does not match.
the current error I am getting is:
"Syntax error: expected something between the 'DELETE' keyword and the 'ELSE' keyword"
Any help appreciated, thanks!

You can make use of MultiStatement DELETE and INSERT statement to correct data from temp table into target table
DELETE FROM TAB_A WHERE EXISTS (SELECT 1 FROM TAB_B WHERE TAB_A.F1 = TAB_B.F1 AND TAB_A.F2 = TAB_B.F2)
;INSERT INTO TAB_A SELECT * FROM TAB_B;

Related

Update a column with row_number with duplicate records without PK

I have a table with duplicate records but without primary key. Data looks like this:
I want to update one empty column with one of column concatenate with row_number. After update, I want to achieve this:
Since the table does not have a unique column, which means I would join back to a CTE or subquery. I know in sql server, it can be done like this:
UPDATE X
SET X.NEW_KEY = X.PERSONNUMBER + '-' + X.NEW_CODE_DEST
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY PERSONNUMBER) AS NEW_CODE_DEST,PERSONNUMBER,NEW_KEY
FROM EMPLOYEE
) as X;
I tried same logic in postgresql but it didn't work. It threw an error:
SQL Error [42P01]: ERROR: relation "x" does not exist
I also tried this in
UPDATE EMPLOYEE
SET NEW_KEY = X.PERSONNUMBER || '-' || X.NEW_CODE_DEST
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY PERSONNUMBER) AS NEW_CODE_DEST,PERSONNUMBER
FROM EMPLOYEE
) as X;
The NEW_KEY is updated with duplicate value, not surprise there.
So is there a equivalent method in to achieve the same update result? Or I have my query wrong?
Really appreciate the help!

PSQL - UPDATE tableA off tableB where Column1 Match

I have a broken column with null values, however I have managed to import the data off a csv into TempTable
MediaRecords - localpath column is null
TempTable - localpath column is correct
UPDATE mediarecords
SET localpath = TempTable.localpath
FROM TempTable
WHERE recordid = TempTable.recordid;
I keep getting ERROR: relation "temptable" does not exist
LINE 3: FROM TempTable
however I can browse the table and see the data.
I tried following this How to update selected rows with values from a CSV file in Postgres? and here we are
Hu Bucky, can you check how the table is actually called because I see you referring at it as TempTable with camelcase and the error states temptable all lowercase.
PostgreSQL could be case sensitive. As example if you do the following
create table "TempTableABC" (id int);
Trying to select from temptableABC will fail
defaultdb=> select * from temptableABC;
ERROR: relation "temptableabc" does not exist
LINE 1: select * from temptableABC;
^
You'll need to use the same quoted syntax to make it work
defaultdb=> select * from "TempTableABC";
id
----
(0 rows)
UPDATE mediarecords
SET localpath = "TempTable".localpath
FROM public."TempTable"
WHERE "mediarecords".recordid = "TempTable".recordid;
Worked

SQL update statements updates wrong fields

I have the following code in Postgres
select op.url from identity.legal_entity le
join identity.profile op on le.legal_entity_id =op.legal_entity_id
where op.global_id = '8wyvr9wkd7kpg1n0q4klhkc4g'
which returns 1 row.
Then I try to update the url field with the following:
update identity.profile
set url = 'htpp:sam'
where identity.profile.url in (
select op.url from identity.legal_entity le
join identity.profile op on le.legal_entity_id =op.legal_entity_id
where global_id = '8wyvr9wkd7kpg1n0q4klhkc4g'
);
But the above ends up updating more than 1 row, actually all of the rows of the identity table.
I would assume since the first postgres statement returns one row, only one row at most can be updated, but I am getting the wrong effect where all of the rows are being updated. Why ?? Please help a nubie fix the above update statement.
Instead of using profile.url to identify the row you want to update, use the primary key. That is what it is there for.
So if the primary key column is called id, the statement could be modified to:
UPDATE identity.profile
SET ...
WHERE identity.profile.id IN (SELECT op.id FROM ...);
But you can do this much simpler in PostgreSQL with
UPDATE identity.profile op
SET url = 'htpp:sam'
FROM identity.legal_entity le
WHERE le.legal_entity_id = op.legal_entity_id
AND le.global_id = '8wyvr9wkd7kpg1n0q4klhkc4g';

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';

postgresql "insert ... on conflict ... update" how to specify which row to update from

I have no idea how to make this work, hope you can help me
I have a table "student_to_course_term" containing the columns "course_term_id", "student_id", "student_mc_worksheet_id" and "id"
What I want to achieve is to copy all rows with course_term_id=19 to new rows with course_term_id=23. If row already exists, update the "student_mc_worksheet_id".
This is my code so far, but I'm not sure how to access the row with course_term_id=19 and course_term_id=23 after the "on conflict do update set" part. Any help appreciated!
INSERT INTO public.student_to_course_term
(course_term_id, student_id, student_mc_worksheet_id)
SELECT 23, student_id, student_mc_worksheet_id
FROM public.student_to_course_term
WHERE course_term_id = 19
ON CONFLICT ON CONSTRAINT student_to_course_term_student_id_course_term_id_key
DO UPDATE
SET student_mc_worksheet_id ( =>from the student_mc_worksheet_id=23 row) = student_mc_worksheet_id ( => from the student_mc_worksheet_id=19 row) ;