Update inner join result Oracle - sql

In my java code I have foreach loop which iterates though list
foreach(MyObject obj:list){
String status = obj.getStatus();
String is = obj.getId();
// DB call
1. To update Status in Table A
jdbcobj.updtastatus(status,id);
2. Get status from table B
String tableBStatu= jdbcobj.getstatufromtableB(status,id):
obj.setStatus(tableBStatus):
}
To avoid 2 dB calls in for loop I am using inner join and trying to achieve same output as above
I am using inner-join and get the new result set based on common field.I want to update the result set but I am unable to figure out how?
I have two tables "A" and "B".
Table "A" has columns id,name,statusA
Table "B" has columns id,city,statusB
As stated at start, I am using inner-join and my query looks like this.
Select A.id A.statusA,B.statusB FROM A INNER JOIN ON B where A.id=B.id
Which gives me result as "id", status from table "A" and status from table "B".
Now i want use the inner-join result, to update statusA column from table "A" and set value ="DONE"
And want to use the statusB column value in java object.
String statusfromColumnB = get statusB col value
and set in my java object like this
myObj.setStatus(statusfromColumnB)
Sample Data
Suggest a solution.

If I understand you correctly, an Oracle MERGE query could properly respond to your need :
Consider :
MERGE INTO A
USING B ON (A.id = B.id)
WHEN MATCHED THEN UPDATE SET A.statusA = B.statusB
This query will update the status in table A from that of the corresponding record in table B.
Oracle merge is a vendor-specific statement that is optimized for multi-rows upserts (inserts/updates).
Demo on DB Fiddle :
Select A.id, A.statusA, B.statusB FROM A INNER JOIN B ON A.id=B.id
ID | STATUSA | STATUSB
-: | :------ | :--------
1 | Pending | Initiated
2 | Pending | Completed
MERGE INTO A
USING B ON (A.id = B.id)
WHEN MATCHED THEN UPDATE SET A.statusA = B.statusB
2 rows affected
Select A.id, A.statusA, B.statusB FROM A INNER JOIN B ON A.id=B.id
ID | STATUSA | STATUSB
-: | :-------- | :--------
1 | Initiated | Initiated
2 | Completed | Completed
If you want to set statusA to a fixed value instead, then you could go :
MERGE INTO A
USING B ON (A.id = B.id)
WHEN MATCHED THEN UPDATE SET A.statusA = 'Finished'

Do you want something like this?
update a
set (status, somewhereelsecolumn) =
(select 'DONE', <whatever>
from b
where A.id = B.id
)
where exists (select 1 from b where a.id = b.id);

Related

sql return json object by status from two tables with different number of rows

I am using PostgreSQL 9.5
I have two table:
A
ID | isStatusA | IsStatusB | IsStatusC
0 | true | false | true
A table has only 1 row for data i need. Also i have B table with:
ID | status | a_id
0 | A | 0
0 | C | 0
When i wrote my select with "from A inner join B on a.id = b.a_id" that i get 2 rows. I have to get only one row (or json object) with checking that is that true/false in table A and is status present in table B. To return true i have to check both conditions.
I want {A: true, B: false, C:true} or something similar with using pivot.
Using PostgreSQL ARRAY_AGG() function along with GROUP BY to "denormalize" the B table status column. Then INNER JOIN table A with an ad hoc, temporary table, here named B_agg.
SELECT A.*, B_agg.status_agg
FROM A
INNER JOIN (
SELECT a_id, ARRAY_AGG(status) status_agg FROM B GROUP BY a_id
) B_agg ON A.ID = B_agg.a_id
;
Output:
id
isstatusa
isstatusb
isstatusc
status_agg
0
t
t
f
{A,C}
The temporary table query:
SELECT a_id, ARRAY_AGG(status) status_agg FROM B GROUP BY a_id
...outputs:
a_id
status_agg
0
{A,C}
This result is then is INNER JOIN'ed with table A connecting columns A.ID and B_agg.a_id: ON A.ID = B_agg.a_id.
The temporary table is given the alias B_agg for access outside the temporary table query, such as: B_agg.status_agg.
Try it here: https://onecompiler.com/postgresql/3yfyffrrg
Credit to: https://stackoverflow.com/a/6558226/2743458
Using JSON_AGG() and JSON_BUILD_OBJECT() to create a JSON object and assign desired object key names:
SELECT JSON_AGG(
JSON_BUILD_OBJECT('A',isStatusA,'B',isStatusB,'C',isStatusB)
) status_agg
FROM A
;
Output:
status_agg
[{"A" : true, "B" : true, "C" : true}]
Try it here: https://onecompiler.com/postgresql/3yfyjt24r
The A table provides all the information necessary to produce the output {A: true, B: false, C:true}.
Can also including the ID column in case multiple IDs are collected in a single query:
SELECT JSON_AGG(
JSON_BUILD_OBJECT(ID,
JSON_BUILD_OBJECT('A',isStatusA,'B',isStatusB,'C',isStatusB)
)
) status_agg
FROM A
;
Output:
status_agg
[{"0" : {"A" : true, "B" : true, "C" : true}}]

How to generate the newid when there is change in column value in sql server

Consider below example
ID| RecordUID | Person |Value
1 |49D62793-989B-4135-9873-21572D511297| Test |10
2 |49D62793-989B-4135-9873-21572D511297| Test |11
3 |DDB40B89-2BB4-4536-9847-32B9F53C0196| Test1 |21
how to generate the above new id(RecordUID(NewID())) when there is a change in the value of a person column?
I need for a select query like
Select ID,NewID() when a change in Person, value from Table A
Thanks In Advance!!!
I suppose you're looking for an AFTER UPDATE TRIGGER as the following
CREATE TRIGGER MyTrig
ON Data
AFTER UPDATE
AS
UPDATE D
SET RecordUID = NEWID()
FROM Data D
JOIN (
SELECT I.Id
FROM INSERTED I
JOIN DELETED D ON I.Id = D.Id AND I.Person <> D.Person
) T ON D.Id = T.Id;
Here is a db<>fiddle where you can see how it's working online.

Return only 1 value from a table that is related to a child table with multiple related records

Table A contains an ID that is related to table B. Table B also contains an ID that is related to table C. I need to figure out how to bring back only one value, based on a hierarchy that is defined outside of the tables.
For Example:
Table A (Devices)
-------------------------
| DeviceID | Device Name |
-------------------------
|___001____| Server1_____|
--------------------------
|___002____| server2_____|
--------------------------
Table B (Translation Table)
-------------------------
| DeviceID | Value ID |
-------------------------
|___001____|____456______|
--------------------------
|___002____|____456______|
--------------------------
|___001____|____789______|
--------------------------
|___002____|____123______|
Table C (Value Table)
-------------------------
|_ValueID__|___Value_____|
-------------------------
|___123____|____LOW______|
--------------------------
|___456____|____MED______|
--------------------------
|___789____|____HIGH_____|
--------------------------
What I need is to evaluate each ID from table a and if it has a related value for HIGH (789) I need to bring back HIGH, if it DOESN'T if a related HIGH value then I need to check and see if it is related to a MED value. If the device is not related to a HIGH value but it is related to a MED value, then bring back MED. Lastly doing the same thing for LOW. Devices that don't have a value do not need to be returned.
Desired Output
------------------------------
|___Device Name___|___COST___|
------------------------------
|___Server1_______|___HIGH___|
------------------------------
|___Server2_______|___MED____|
------------------------------
How would i right a query for this information, especially if it is possible for the value ID's to change.
select a.*,
coalesce(
(select C.value from C, B
where c.Value = 'HIGH'
and b.ValueID = c.ValueID
and b.DeviceID = a.DeviceID),
(select C.value from C, B
where c.Value = 'MED'
and b.ValueID = c.ValueID
and b.DeviceID = a.DeviceID),
(select C.value from C, B
where c.Value = 'LOW'
and b.ValueID = c.ValueID
and b.DeviceID = a.DeviceID)
) Value
from a
where exists (select null from C,B
where b.ValueID = c.ValueID
and b.DeviceID = a.DeviceID)
The coalesce will return the first not null value, which probably satisfies your desires.
Based on your inputs and desired output, following query may give desired result:
select a.DeviceName, c.Value
from TableA a inner join TableB b
on a.DeviceID=b.DeviceID
inner Join TableC c
on b.ValueID=c.ValueID

How to use one table as a filter from other and generate a new one in sql

say that I have a table that needs to be used as a filter table(table A) vs other one which reads data from a linkedserver (table b). The result of the filtering will generate a third table, the thing is I can not figure it out how to apply this filtering correctly. I found reference from this link: Reference but it does not onboard what I am looking for.
See as following:
Table A - data type in columns is Bit
|Field1 |Field2 |Field3 |Field4 |CustomerCode|
|-------|-------|-------|-------|-------------|
| 1 | 0 | 0 | 1 | c001 |
Table B - data type in columns is varchar
|FieldA |FieldB |FieldC |FieldD |CustomerCode |
|------- |-------|-------|-------|-------------|
| aaaaa | null | ccccc |ddddd | c001 |
Then what I seeking is something like this:
IF tableA.Field1 = 1 THEN NOT EMPTY tableB.FieldA
Do an INSERT INTO tableC FieldI VALUES(tableB.FieldA)
ELSE INSERT INTO tableC FieldI VALUES ('No Value Found')
So this will ensure that for all fields from table A are equal 1,
then for table B data can not be null, if data is null just insert that message: 'No Value Found'; if data is not null, then just place the data from table B to that table C.
I am starting with SQL and mostly I am missing something that could make it easier to digest this issue.
Thanks
Use INSERT INTO tableC ... SELECT FROM. Something like this should work:
INSERT INTO tableC
SELECT COALESCE(t1.FieldA, 'No Value Found'),
COALESCE(t1.FieldB, 'No Value Found'),
COALESCE(t1.FieldC, 'No Value Found'),
COALESCE(t1.FieldD, 'No Value Found')
FROM TableB t1
INNER JOIN TableA t2
ON t1.CustomerCode = t2.CustomerCode
WHERE t2.Field1 = 1 AND
t2.Field2 = 1 AND
t2.Field3 = 1 AND
t2.Field4 = 1

How to Update common column values from different values in SQL server?

I have two tables. My first table A contains
Tran_Particular | Dr_Tran_Amt | BeneficiaryName | PRNNo
columns.
My second table B contains
BeneficiaryName | Dr_Tran_Amt | PRNNo
columns.
I want to update table A.PRNNo but When I am updating this on BeneficiaryName and Dr_Tran_Amt that time it updates only first value. But In table B there are two PRNNO's are exist and In table A also two different Tran_Particular are exist. I want to update unique PRNNO wrt Tran_Particular, BeneficiaryName and Dr_Tran_Amt.
Query.
update A
set a.PRNNo = b.PRNNo
from A a
inner join B b
on a.Dr_Tran_Amt= b.Amount
and a.BeneficiaryName = b.BeneficiaryName;
HoW to update this in SQL server.
The code below should get you only the first matching row (the lowest PRNNo value):
UPDATE A
SET a.PRNNo = b.PRNNo
FROM A a
INNER join B b
ON a.Dr_Tran_Amt = b.Amount
AND a.BeneficiaryName = b.BeneficiaryName
AND b.PRNNo = (SELECT MIN(c.PRNNo) FROM B c WHERE c.BeneficiaryName = B.BeneficiaryName AND c.Dr_Tran_Amt = b.Dr_Tran_Amt);