Update query comparing two tables - Oracle - sql

I am trying to change the sign of amount field in tdataseg table when the account_type in aif_hyp_acct_type table is ' ','R','L','Q'. aif_hyp_acct_type is the master table. It has loadid, account and account_type fields. tdataseg table has account, amount and many other fields.
I tried this query and get ORA-01427 error.
Single row subquery returns more than one row.
update tdataseg
set tdataseg.amount =
(select decode(sign(tdataseg.amount),-1,abs(tdataseg.amount),1,-abs(tdataseg.amount),0)
from tdataseg, aif_hyp_acct_type
where tdataseg.loadid = aif_hyp_acct_type.loadid
and tdataseg.account = aif_hyp_acct_type.account
and aif_hyp_acct_type.account_type in (' ','R','L','Q'))

Presumably the problem is that you think you have a correlated subquery, but you don't. The outer table is mentioned in the inner query. You need to remove that reference:
update tdataseg
set tdataseg.amount = (select decode(sign(tdataseg.amount), -1, abs(tdataseg.amount),
1,-abs(tdataseg.amount), 0)
from aif_hyp_acct_type
where tdataseg.loadid = aif_hyp_acct_type.loadid and
tdataseg.account = aif_hyp_acct_type.account and
aif_hyp_acct_type.account_type in (' ','R','L','Q')
);
EDIT:
You would get that error if there were no matches and the column were declared not null. Here is one fix:
update tdataseg
set tdataseg.amount = (select coalesce(max(decode(sign(tdataseg.amount), -1, abs(tdataseg.amount),
1,-abs(tdataseg.amount), 0)), 0)
from aif_hyp_acct_type
where tdataseg.loadid = aif_hyp_acct_type.loadid and
tdataseg.account = aif_hyp_acct_type.account and
aif_hyp_acct_type.account_type in (' ','R','L','Q')
);
That will set non-matches to 0.

I'd try to solve such update problems with a MERGE statement. I find it a bit more natural to write.
MERGE INTO tdataseg
USING (
SELECT loadid, account
FROM aif_hyp_acct_type
WHERE account_type IN (' ','R','L','Q')
) q
ON (tdataseg.loadid=q.loadid AND tdataseg.account=q.account)
WHEN MATCHED THEN UPDATE SET amount = - ABS(amount);
You put the table you want to change after the MERGE INTO. The master table is subsetted in the USING query. The join condition goes into the ON clause, and the actual data change is specified after WHEN MATCHED THEN UPDATE SET.

Related

Converting a delete statement into a where clause, T-sql

I have removed rows from a results table after it has been built already. I have decided to try to remove the rows from being inserted into the results table in the first place instead.
To remove the appropriate rows from the results table after the fact I used:
if #InterchangeAction = 'HCR'
begin
--Do not allow claims to be output if they have a prior submission marked 'output'
--and the interchange 'output submission action' is marked as 'hold'
delete from #ResultSet
where exists ( select 1 from ClaimSubmissions CS inner join InterchangeInfo I on CS.InterchangeId = I.InterchangeId
where #ResultSet.ClaimId = CS.ClaimId
and CS.InterchangeId = #InterchangeID
and CS.SubmissionStatus = 'OPT'
and CS.OutputDate is not NULL
)
end
This works as I want but I am thinking it would be more efficient to stop the rows from being added in the first place.
I'm going to start my check with:
if #InterchangeAction = 'HCR'
and then concatenate on to the existing where clause but I am unsure on how to convert the delete statement into a where clause?
Any pointers on where to start would be greatly appreciated.
Unless I'm missing something obvious, aren't you just looking for this?:
INSERT #ResultSet
(<Column List>)
SELECT
<Column List>
FROM
WhatHaveYou AS WHY
WHERE NOT EXISTS ( select 1 from ClaimSubmissions CS
inner join InterchangeInfo I
on CS.InterchangeId = I.InterchangeId
where WHY.ClaimId = CS.ClaimId
and CS.InterchangeId = #InterchangeID
and CS.SubmissionStatus = 'OPT'
and CS.OutputDate is not NULL
)

Update largest date, matching two fields

tables
Hi, I'm looking to update the last column in a blank table. Picture shows input and desired output. Trying to pick the largest date where workorder and state match.
I've tried a couple different codes:
UPDATE mytable
SET mytable.orderstartdate = MAX(table2.earliestdate)
FROM mytable as table2
WHERE (mytable.workorder = table2.workorder AND
mytable.state = table2.state)
;
"Syntax Error (missing operator) in query expression 'MAX(table2.earliestdate) FROM mytable as table2'."
UPDATE mytable
SET mytable.orderstartdate = (
SELECT max(earliestdate)
FROM mytable as table2
WHERE (mytable.workorder = table2.workorder AND
mytable.state = table2.state)
)
;
"Operation must use an updateable query"
Edit - click tables link for image.
Write PL/SQL Code.
First, select DISTINCT WorkOrder and State and capture in variables.
Now, Iterate the list and Write a query to get max date i.e. max(date) using work_order and State in where clause. Capture the
date.
Now, In the same loop write update query setting max(date) and workorder and State in where clause.
UPDATE table A
SET A.orderstartDate = (SELECT max(earliestdate)
FROM table B
WHERE A.WorkOrder = B.WorkOrder
GROUP BY WorkOrder)
not sure if access supports correlated subqueries but if it does...
and if not...
UPDATE table A
INNER JOIN (SELECT WorkOrder, max(OrderStartDate) MOSD
FROM Table B
GROUP BY WorkOrder) C
ON A.WorkOrder = C.workOrder
SET A.OrderStartDate = C.MOSD
Check database open mode, it may be locked for editing, or you may have no permission to to file.

Fetching and concatenate two rows value from two different table in SQL

I am unable to Fetch and concatenate two rows value from two different table in SQL.
Please see my query in attached photo.
Following query doesn't providing me the exact data
SELECT RequestNo+'::'+convert(varchar(200),(select count(RID)+1
from BDProjectProposal
Group by RID)) AS Number
FROM BDRequestorInfo
WHERE (RID = #RID)
Is there any way?
You should use a correlated subquery:
SELECT (RequestNo + '::' +
convert(varchar(200),
(select count(RID) + 1
from BDProjectProposal pp
where pp.RID = ri.RID)
)
)
) AS Number
FROM BDRequestorInfo ri
WHERE ri.RID = #RID;
Can you try below
SELECT RequestNo+'::'+convert(varchar(200),isnull((select count(RID)+1
from BDProjectProposal
Group by RID
having RID = #RID),1) AS Number
FROM BDRequestorInfo
WHERE (RID = #RID)
I only added WHERE clause (having RID = #RID) in Subselect to ensure that there will be only one value returning.
Your subselect returns a dataset causing possibly an SQL error
I modified above query and added ISNULL(....,1) for NULL returns with no rows for a given #RID

Oracle SQL, trying to get one value from a select/join to use to update one column in one table?

I have one table with the following columns:
T_RESOLVED_DATE
I_HOUSEHOLD_NUMBER
I_RESOLVED_SET_NUMBER
I_STATION_CODE
I_RESOLVED_START_MIN
I_DURATION
I_PERSON_NUMBER
I_COVIEW_DEMO_ID
Initially, I_COVIEW_DEMO_ID is set to null.
Then I have another table with the following columns:
T_RESOLVED_DATE
I_HOUSEHOLD_NUMBER
I_PERSON_NUMBER
I_AGE
T_GENDER
I_COVIEW_DEMO_ID
I am trying to update I_COVIEW_DEMO_ID in the first table by using the value of I_COVIEW_DEMO_ID in the second table where the T_RESOLVED_DATE, I_HOUSEHOLD_NUMBER, and I_PERSON_NUMBER are equal in both tables. The first table may contain multiple rows with the same DATE, HOUSEHOLD_NUMBER, and PERSON_NUMBER, because the rows can vary by the rest of the columns.
I have tried to do a select and a group by which seems to get me part way there, but I am getting a "single-row subquery returns more than one row" error when I try to update the columns in the first table. This is what I've tried, along with variations of it:
UPDATE
Table1
SET
I_COVIEW_DEMO_ID =
(SELECT
b.I_COVIEW_DEMO_ID
FROM Table1 a,
Table2 b
WHERE a.I_HOUSEHOLD_NUMBER = b.I_HOUSEHOLD_NUMBER AND
a.I_PERSON_NUMBER = b.I_PERSON_NUMBER AND
a.T_RESOLVED_DATE = b.T_RESOLVED_DATE
GROUP BY b.I_COVIEW_DEMO_ID);
Any suggestions?
I was able to get it to work using this statement:
MERGE INTO table1 a
USING
(
SELECT DISTINCT
T_RESOLVED_DATE,
I_HOUSEHOLD_NUMBER,
I_PERSON_NUMBER,
I_COVIEW_DEMO_ID
FROM
table2
) b
ON
(
a.T_RESOLVED_DATE = b.T_RESOLVED_DATE
AND a.I_HOUSEHOLD_NUMBER = b.I_HOUSEHOLD_NUMBER
AND a.I_PERSON_NUMBER = b.I_PERSON_NUMBER
) WHEN MATCHED THEN
UPDATE SET
a.I_COVIEW_DEMO_ID = b.I_COVIEW_DEMO_ID;
As per our discussion on the comments this would be a simple PLSQL block to do what you need. I'm doing direct from my head without test, so you may need to fix some sintaxe mistake.
BEGIN
FOR rs IN ( SELECT I_HOUSEHOLD_NUMBER,
I_PERSON_NUMBER,
I_COVIEW_DEMO_ID,
T_RESOLVED_DATE
FROM Table2 ) LOOP
UPDATE Table1
SET I_COVIEW_DEMO_ID = rs.I_COVIEW_DEMO_ID
WHERE I_PERSON_NUMBER = rs.I_PERSON_NUMBER
AND I_HOUSEHOLD_NUMBER = rs.I_HOUSEHOLD_NUMBER
AND T_RESOLVED_DATE = rs.T_RESOLVED_DATE;
END LOOP;
--commit after all updates, if there is many rows you should consider in
--making commits by blocks. Define a count and increment it whithin the for
--after some number of updates you commit and restart the counter
COMMIT;
END;

How to copy column values from one database to empty column in other database?

I have two databases.
Alarm
TMP
I have a table in Alarm, where in a table there is one empty column with null values.
And I have a single column table in TMP.
I want to copy this single column values to my table in Alarm database.
What I tried so far is,
update [Alarm].[dbo].[AlarmDetails] set Alarm_Message = (select * from [TMP].[dbo].[AlarmDetails$])
where 1=1
The error is
Subquery returned more than 1 value.
Please note this,
NOTE: There is no id column in source table. Only one table & one column, Alarm Message.
I know the cause of error, but how should I modify my SQL.
Thank You.
Here's an example of copying a column:
update dst
set Alarm_Message = src.AlarmMessage
from Alarm.dbo.AlarmDetails dst
join TMP.dbo.AlarmDetails src
on dst.id = src.id
You did not specify how the tables are related, so I assumed they both have an id column.
You need something like this.
update t1
set
t1.<something1> = t2.<something2>
from
[Alarm].[dbo].[AlarmDetails] t1
join [TMP].[dbo].[AlarmDetails] t2 on (t1.<cols1> = t2.<cols2>)
UPDATE results SET results.platform_to_insert = (
SELECT correct_platform
FROM build
WHERE results.BuildID=build.BuildID LIMIT 1
);