Update child field with parent field if child's field is NULL [duplicate] - firebird

This question already has answers here:
Update a table with join?
(2 answers)
Closed 4 years ago.
I've two tables PURCHASE_ORDER_HDR and PURCHASE_ORDER_DET. Linked with key POH_ID.
Both Header and Detail table contains DELIVERYDATE where detail's Delivery Date can be null.
I want to update PURCHASE_ORDER_DET with Header's Delivery Date where Detail's Delivery Date is NULL
Tried the something like following, which is not syntactically correct.
UPDATE PURCHASE_ORDER_DET pod
INNER JOIN
(
SELECT poh.POH_ID as parentId,
poh.DELIVERYDATE as dlvDate
FROM PURCHASE_ORDER_HDR poh
) parent on pod.POH_ID = parent.parentId
SET
pod.DELIVERYDATE = parent.dlvDate
WHERE
pod.DELIVERYDATE = null
EDIT
As suggested by Mark here, I tried the following with it's equivalent MERGE statement.
UPDATE pod
SET pod.DELIVERYDATE = poh.DELIVERYDATE
FROM PURCHASE_ORDER_DET pod JOIN PURCHASE_ORDER_HDR poh ON poh.POH_ID = pod.POH_ID
WHERE pod.DELIVERYDATE = null
The equivalent MERGE statement is
MERGE INTO PURCHASE_ORDER_DET AS pod
USING PURCHASE_ORDER_HDR AS poh
ON poh.POH_ID = pod.POH_ID AND pod.DELIVERYDATE = NULL
WHEN MATCHED THEN
UPDATE SET pod.DELIVERYDATE = poh.DELIVERYDATE
It does execute but no row get effected.

Thanks Mark, This worked for me.
MERGE INTO PURCHASE_ORDER_DET AS pod
USING PURCHASE_ORDER_HDR AS poh
ON poh.POH_ID = pod.POH_ID AND pod.DELIVERYDATE is NULL
WHEN MATCHED THEN
UPDATE SET pod.DELIVERYDATE = poh.DELIVERYDATE

Related

Multipart column names in update statement with select

I'm sure this could be a duplicate but I can't seem to find the right search phrase.
Given a table in a named schema (i.e. not dbo) requires you include the schema name in the statement. So previously I'd have simply written it as so:
UPDATE [Schema].[Table1]
SET [AColumn] =
(
SELECT [SomeColumn]
FROM [Schema].[Table2]
WHERE [Schema].[Table2].[SameColumnName] = [Schema].[Table1].[SameColumnName]
);
But since More than two-part column name is deprecated, I need to find a new way to do this which is future proof. I have come up with 2 options, firstly using an alias:
UPDATE [Alias1]
SET [AColumn] =
(
SELECT [SomeColumn]
FROM [Schema].[Table2] [Alias2]
WHERE [Alias2].[SameColumnName] = [Alias1].[SameColumnName]
)
FROM [Schema].[Table1] [Alias1];
The second way is the one I'm really having trouble finding out if it's truly VALID T-Sql:
UPDATE [Schema].[Table1]
SET [AColumn] =
(
SELECT [SomeColumn]
FROM [Schema].[Table2]
WHERE [Table2].[SameColumnName] = [Table1].[SameColumnName]
);
I have tested both and they work, so my question is, is the second completely valid and normal to use just the table name without the Schema in this sense or should I rather opt for the slightly more verbose Alias?
As I said in my comment, alias your objects.
SELECT MT.MyColumn,
YT.MyColumn
FROM dbo.MyTable MT
JOIN so.YourTable YT ON MT.ID = YT.fID
WHERE YT.[name] = N'Jane';
If you're performing an UPDATE, then specify the alias of the object to Update:
UPDATE MT
SET MyColumn = YT.MyColumn --Column on the left side of the SET will always reference the table being updated
FROM dbo.MyTable MT
JOIN so.YourTable YT ON MT.ID = YT.fID
WHERE YT.[name] = N'Jane';

How to update multiple fields in two tables using inner join

I've two tables. And I need two fields to update.
they are connected to each other with a foreign key. I would like to update the fields found in these two tables by using my inner join.
UPDATE cert
SET cert.status = 1, doc.status = 1
FROM certificates cert
INNER JOIN documents doc ON doc.data_id = cert.certificate_id
WHERE cert.status = 0 AND cert.user_id = _expert_id AND doc.data_type = 'CERTIFICATE';
The code I mentioned above allows me to update the status field in the certificates table only. In addition, I would like to update the field in the documents table
Maybe this helps:
demo:db<>fiddle
WITH cert_update AS (
UPDATE certificates cert
SET status = 1
FROM documents doc
WHERE doc.data_id = cert.certificate_id
AND cert.status = 0
AND cert.user_id = '2' -- your "_expert_id"
AND doc.data_type = 'CERTIFICATE'
RETURNING certificate_id
)
UPDATE documents doc
SET status = 1
FROM cert_update cert
WHERE doc.data_id = cert.certificate_id
AND doc.data_type = 'CERTIFICATE';
Using the WITH clause (CTE) you are able to do several updates in one query. The first one gives back the updated certificate_id which can be used in the second query.

Postgresql - Rule with On Conflict Statement

I have a table in postgres with columns link(PK), person, places and date. I would like to create a rule that when insert is command is issued from my backend program then if there is a conflict on the link column it would do an upsert ( update the person, places and date) columns for the same link. I cannot figure out the format of the rule. Below is pseudo code of what I am looking for.
Create Rule rssmodel as on
INSERT into public.rssmodel
On conflict (link)
do UPDATE public.rssmodel
set person = data, places=data, date=data
You could do something like this to achieve that:
CREATE RULE rssmodel_insert AS ON
INSERT TO public.rssmodel
WHERE EXISTS (SELECT 1 from rssmodel where NEW.link = link)
DO INSTEAD
UPDATE public.rssmodel
SET person = NEW.person, places = NEW.places, date = NEW.date WHERE link = NEW.link;

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

Update columns based on subquery containing "select unnest" clause

I am attempting to update a boolean column in one table based upon the values in a second.
UPDATE channels
SET contains_photos = TRUE
WHERE id IN (SELECT unnest(ancestors)
FROM channel_tree WHERE id = 11329);
The channel_tree.ancestors column contains an array of channel IDs. The above is failing with the following error:
ERROR: cannot TRUNCATE "channel_tree" because it is being used by active queries in this session
The overriding goal is to set the contains_photos column to true for all ancestors of a given channel. Any one know how best to alleviate this error, or even an alternative solution?
No idea why your error says TRUNCATE. It sounds like you have a trigger or rule that is doing a truncate that we can't see.
Here's some alternative ways of doing that same query:
UPDATE channels
SET contains_photos = TRUE
WHERE id = ANY (SELECT ancestors
FROM channel_tree WHERE id = 11329);
Or with a join:
UPDATE channels
SET contains_photos = TRUE
FROM channel_tree
WHERE channels.id = ANY (channel_tree.ancestors)
AND channel_tree.id = 11329;