Multiple columns updation in single query - sql

Can I update two columns in different tables with single update query.
I stuck in a situation where I have :
Table 1:
case id client id created by
1 a john
2 b Mike
3 c Raghu
4 b Mike
Table 2:
case id client id case cost
2 b 5,000
3 j 10,000
4 b 6,000
The problem is , I want to update client id=d in both the tables of those cases created by Mike.
I can fetch out those cases through join which is created by mike but is it possible to update them also by using sql joins??

The answer to more updates in one statement is no. While you can enter multiple tables in the from clause of an update statement, you can only specify a single table after the update keyword. Even if you do write a "updatable" view (which is simply a view that follows certain restrictions), updates like this will fail.
To fix this
Use transaction block:
Example :
BEGIN TRANSACTION
update A
set A.client_id = 'd'
from table1 A inner join table2 B
on B.client_id = A.client_id
where a.created_by='mike'
update B
set B.client_id = 'd'
from table2 B inner join table1 A
on B.client_id = A.client_id
where a.created_by='mike'
COMMIT

Probably something like this will work
UPDATE table1,table2 SET table1.client_id='d',table2.client_id='d'
WHERE table1.client_id=table2.client_id;
Since you mentioned RDBMS as MSSQL 2012; you can have only single update statement.
You can either have multiple in transaction block as mentioned in another answer (OR)
Create a procedure and wrap both your update statement there like
create procedure update_table1_table2
as
begin
UPDATE table1 SET client_id='d' WHERE client_id='b';
UPDATE table2 SET client_id='d' WHERE client_id='b';
end
Then call your procedure like
exec update_table1_table2

Related

Update table column based on two other table values

I need to update a column in one of my tables based on data from 2 other tables.
So I want the column isAvailable, in the table questionObjectives, to be set to 1 based on 2 conditions and this is what I have:
UPDATE
dbo.questObjectives
SET
isAvailable = 1
FROM
dbo.questObjectives qo
INNER JOIN
dbo.dungeonList dl
ON
qo.questID = dl.questID
WHERE dl.dungeonType = 17
AND qo.objectiveID IN(SELECT objectiveID FROM gameMissions)
So to translate, isAvailable should be set to 1 if:
the linked dungeonList type is 17
the questionObjectives objectiveID is in the table gameMissions
So I thought I had my logic right, but I keep getting this error:
'invalid column name isAvailable.'
But it is there. It is in the questionObjectives table so I'm not sure what I'm doing wrong.
Any ideas?
Thanks!
Is this what you want?
update qo
set qo.isavailable = 1
from questObjectives qo
inner join dungeonList dl on qo.questID = dl.questID
where
dl.dungeonList = 17
and exists (select 1 from gameMissions gm where gm.objectiveID = qo.objectiveID)
The main problem with your query is that you have target table questObjectives both in the update and from clauses; you should have it just once, in the from clause, and then refer to the alias in the update clause.
I also rewrote the in condition as a correlated subquery with exists - the logic is the same, but this might perform better.

Update 2 joined tables simultaneously on HANA?

Can I update 2 columns from 2 tables joined by foreign key with one statement in SAP HANA
No, SAP HANA up to its current version HANA 2 SPS 05 does not support multi-table updates (or inserts/deleted for that matter).
Depending on the use-case, you may be able to emulate the behavior via SQLScript, like e.g. so:
DO BEGIN
data_to_insert = SELECT id, stuff FROM DB;
-- update table 1
UPDATE tab1 t FROM t, :data_to_insert d
SET t.one_stuff = d.stuff
WHERE t.id = d.id;
-- update table 2
UPDATE tab2 t FROM t, :data_to_insert d
SET t.two_stuff = d.stuff
WHERE t.id = d.id;
END;

SQL - Update multiple tables, the same column across one query

I have a postgres database
There are 3 tables, I'm trying to make a sql UPDATE statement that updates an active column in each table.
Table1 has a field record that looks like this:
table1_id: 40b77068-4693-4593-8ea9-996501414101
table1_name: Digital Only
active: false
Table2
table2_id: [some randomId we don't care about]
table1_fk: 40b77068-4693-4593-8ea9-996501414101
active: false
Table3 is the same as table 2
table2_id: [some randomId we don't care about]
table1_fk: 40b77068-4693-4593-8ea9-996501414101
active: false
I need a query that looks for the name "Digital Only" and it's ID on table1. Update it's active column. Update corresponding active columns in the 2 other tables matching the original ID in table1
The tables have pretty long names so ideally I want to alias them:
So far I have something along the lines of this in pseudocode
UPDATE a.active, b.active, c.active
INNER JOIN
FROM table1 a, table2 b, table3 c
SET a.active=true, b.active=true, c.active=true
WHERE a.active=true, b.active=true, c.active=true
Not sure how to do this. The table relationships look like this:
I think this does what you want. The idea is first update table1, and to use the returning clause to return the table1_id, that can be used to update the two other tables:
with
t1 as (
update table1
set active = true
where table1_name = 'Digital Only'
returning table1_id
),
t2 as (
update table2
set active = true
from t1
where table1_fk = t1.table1_id
)
update table3
set active = true
from t1
where table1_fk = t1.table1_id
A single update statement can only update 1 table at a time, so there are three ways to do this:
have your application look up the information and then wrap 3 updates in a single transaction
use a stored procedure to implement the lookup/update logic (then your app only needs to make 1 call)
play some SQL tricks by wrapping 3 update statements into a common table expression. this is the most “clever” way to do it.

Join only selected tables

I have A table, B table 10 different tables(1,2,3,..10). I have to select the data by joining any one/more of those 10 , A, and B tables based on the input.
Ex: If input is only 2,5,8,10 I have to join A, B, 2,5,8, and 10 tables and retrieve the data. If input is only 1 and 7th table , I have to join A , B, 1, and 7 tables and retrieve the data.
---- sample-----
suppose A is a person table with p_id, p_name, order_id,.......
B is an order table with Order_id,.........
each 1-10 tables are shopping items like clothes, shoes, electronics,...etc
now I want to pull person details who orders only clothes and shoes with some other constraints like within these dates or age should be 20 like that
then I have to join only person table, order table, clothes table, and shoe table and retrived the details about the persons who ordered atlease one of both the tables. person having only shoe or only colthes are not required. result will be like how many clothes he orderd and how many shoes he ordered.
Can anyone please give me some idea how to do it.
I am working on oracle db and using SQL.
This is sql-server syntax as far as variables but hopefully you can translate that to oracle variables. Anyway the trick is to use your input variables as conditions on a LEFT JOIN. That way if the condition for your variable is false it just wont return rows from that table. If true it will return matches. If you really want it to be an INNER JOIN rather than a LEFT JOIN then just put a case statement in your WHERE condition to make it true if your variable condition is met.
DECLARE #IncludeT1 BIT, #IncludeT2 BIT
SELECT *
FROM
TableA a
INNER JOIN TableB B
ON a.somecol = b.somecol
LEFT JOIN Table1 t1
ON a.somecol = t1.somecol
AND #IncludeT1 = 1
LEFT JOIN Table2 t2
ON b.somecol = t2.solmcol
AND #IncludeT1 = 1
WHERE
(CASE WHEN (#IncludeT1 = 1 and t1.someid IS NOT NULL) OR #IncludeT1 = 0 THEN 1 ELSE 0 END) = 1
AND (CASE WHEN (#IncludeT2 = 1 and t2.someid IS NOT NULL) OR #IncludeT2 = 0 THEN 1 ELSE 0 END) = 1
You can also do it via dynamic SQL as the other answer suggests there are more considerations if you go that route.
I don't think you can handle this with plain SQL. It looks like you need to use dynamic SQL. Have a stored procedure with parameters for the tables you need to join and then build your query based on how you call that procedure. Run the query with execute immediate... Read more here: https://docs.oracle.com/cloud/latest/db112/LNPLS/dynamic.htm#LNPLS011
Update: Here's a sample with pseudo plsql as I don't have your actual data. This is just to give you an idea on how to proceed - I can't write you actual code with the given information and your setup:
DECLARE
table1 VARCHAR2 (100) := 'Table1';
table2 VARCHAR2 (100) := '';
table3 VARCHAR2 (100) := 'Table2';
...
table10 VARCHAR2 (100) := 'Table10';
query VARCHAR2 (4000) := '';
BEGIN
--create the core join between A and B
query := query || 'select A.p_id, A.p_name, B.order_id from A, B where A.order_id = B.order_id ';
IF (table1 != '') THEN query := query || ' and a.id = table1.id ';
--if statements for the rest of your tables and add the join condition for each table to the query string
...
EXECUTE IMMEDIATE query; --run the query... depends on what you want to do with the returned result you can use RETURN INTO or BULK COLLECT INTO...
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (SQLERRM);
END;
Hope this helps...
It appears your 10 different tables are actually just 10 different categories of Products.
Is it possible to homogenise them all into one big Products table with an additional field for ProductCategory (clothes, shoes, electronics, etc)? Your assignment would then reduce to a simple WHERE on this ProductCategory field.
An equivalent (albeit less efficient) view can be achieved without modifying your schema by UNION-ing all 10 tables together, upon which you can draw your assignment.
I realise this does not directly answer your question, but this would drastically simplify your problem and normalise your database, thereby eliminating the need for a complicated solution (which is always the preferred way to go).
I think you should go for pipe lined function with dynamic sql.
e.g. you will create sql on the fly, execute it with execute immediate, return resuls row by row. Take a look here.
Note that there is no accepted answer, however I think
Vincent Malgrat's
approach will do just fine.

Oracle SQL | Single-row Subquery Update returns more than one row?

this question has been asked a lot it seems, but I can't find any dealing with updates and the ones dealing with other stuff haven't helped. I feel like I'm missing something obvious but I can't put my finger on it.
I have the following query to update my table with IDs from another table to enable matching to a spreadsheet:
update TABLE3 set ITM_CD2 =
(select pi.ITM_CD2
from schema1.PI_TABLE pi,
TABLE3 tb3
where pi.OTHER_ITM_CD = tb3.OTHER_ITM_CD)
I can't actually go through with the update because I keep getting "needs a single-row subquery" issues.
EDIT: I should have mentioned that the pi table is from a separate schema.
EDIT 2: For more detail; this is an example of what I'm trying to obtain:
TABLE 3 currently has this data, for instance:
NAME ----- PRODUCT ----- ITM_CD1 ----- ITM_CD2
X Y 11 NULL
A B 12 NULL
C Y 11 NULL
I'm trying to attach data from this item table so I can get the 2nd itm_cd which will allow me to compare it to a table that has ITM_CD2 but NOT ITM_CD1. The NULLs in TABLE 3 would be replaced with the matching ITM_CD2.
The table I'm trying to take the ITM_CD2 from would look like this:
PRODUCT ----- ITM_CD1 ----- ITM_CD2
A 10 90
Y 11 98
B 12 87
Perhaps you want the main TABLE3 in the sub-query:
update TABLE3 set ITM_CD2 =
(select pi.ITM_CD2
from PI_TABLE pi
where pi.OTHER_ITM_CD = TABLE3.OTHER_ITM_CD)
I like using a merge rather than update for this kind of scenario. It makes the connection between the table you are reading from and the table you are writing to more clear:
MERGE INTO table3 t3
USING pi_table pi
ON (pi.other_itm_cd = t3.other_itm_cd)
WHEN MATCHED THEN
UPDATE SET t3.itm_cd2 = pi.itm_cd2
Try this query
UPDATE ( SELECT t1.Item_CD2,pi.ITM_CD2
FROM table3 t1
join pi_table pi on pi.OTHER_ITM_CD = t1.OTHER_ITM_CD
)
SET t1.Item_CD2=pi.ITM_CD2