Update all rows for one column in a table with data in another table - sql

I appreciate any advice on this..
I have two tables where I have to update a column in my primary table with data that resides in another secondary table. I cannot rely on views, etc as this data has to be able to be edited by the user in APEX in the future. I am basically pre-populating the data for the users to reduce their manual entry.
Primary Table = Table 1
Secondary Table = Table 2
Columns to be updated in Table 1 = FTE_ID, ACCOUNT_TYPE
Columns where the data will come from Table 2 = R_ID, ACCOUNT_TYPE
Common column in both tables = TABLE1.FID AND TABLE2.FID
Here is what I have tried, but I get "single-row subquery returns more than one row" because there are multiple table1.fid rows in table1. I basically want to perform this update for ALL rows where TABLE1.FID = TABLE2.FID.
Here is my attempt:
UPDATE TABLE1
SET TABLE1.FTE_ID =
(SELECT TABLE2.R_ID FROM TABLE2 WHERE TABLE1.FID = TABLE2.FID);
Error:
single-row subquery returns more than one row
Thanks for your help,

You can fix the proximate problem by using aggregation or row number:
UPDATE TABLE1
SET TABLE1.FTE_ID = (SELECT MAX(TABLE2.R_ID)
FROM TABLE2
WHERE TABLE1.FID = TABLE2.FID
);
The subquery can only return one row; it is an "arbitrary" value from the possible matching values.
If the field is a character field and you want all matching values, then perhaps listagg is more appropriate:
UPDATE TABLE1
SET TABLE1.FTE_ID = (SELECT LISTAGG(t2.R_ID, ',') WITHIN GROUP (ORDER BY t2.R_ID)
FROM TABLE2 t2
WHERE TABLE1.FID = t2.FID
);

Related

SQL Server multiply multiple columns by values in a column in a second table

I have a very large data set which has following columns:
[ID] [code_1] [code_2] [code_3] [code_4]
[days_code_1] [days_code_2] [days_code_3] [days_code_4]
The ID column is not unique, the [code_n] columns are text and the [days_code_n] columns are numeric.
In a second table I have two columns, one with code values which match [code_n], and [cost value] which corresponds to each code.
I want to be able to multiply the [days_code_n] by the [cost value]. I can do this individually, but for reasons out of my control I have 50 [code_n] and [days_code_n] columns. As the ID value is not unique I have to keep the data in the current format.
Can anyone advise me how to multiply the values in the code_days column, by the value in [the cost_value] variable in the second table without running 50 queries.
Since you didn't mention the names of your tables I call them Table1 and Table2.
You can join in the second table for every code_n column you have:
SELECT Table1.ID
,Table1.days_code_1 * t2_01.cost_value AS result1
,Table1.days_code_2 * t2_02.cost_value AS result2
,Table1.days_code_3 * t2_03.cost_value AS result3
...
,Table1.days_code_50 * t2_50.cost_value AS result50
FROM Table1
JOIN Table2 t2_01 ON Table1.[code_1] = t2_01.[code_n]
JOIN Table2 t2_02 ON Table1.[code_2] = t2_02.[code_n]
JOIN Table2 t2_03 ON Table1.[code_3] = t2_03.[code_n]
...
JOIN Table2 t2_50 ON Table1.[code_50] = t2_50.[code_n]
And make sure that you have a foreign key on every Table1.code_... column which references Table2.code_n. Otherwise the query could be very slow.

Oracle SQL Update one table column with the value of another table

I have a table A, where there is a column D_DATE with value in the form YYYYMMDD (I am not bothered about the date format). I also happen to have another table B, where there is a column name V_TILL. Now, I want to update the V_TILL column value of table B with the value of D_DATE column in table A which happens to have duplicates as well. Meaning, the inner query can return multiple records from where I form a query to update the table.
I currently have this query written but it throws the error:
ORA-01427: single-row subquery returns more than one row
UPDATE TAB_A t1
SET (V_TILL) = (SELECT TO_DATE(t2.D_DATE,'YYYYMMDD')
FROM B t2
WHERE t1.BR_CODE = t2.BR_CODE
AND t1.BK_CODE = t2.BK_CODE||t2.BR_CODE)
WHERE EXISTS (
SELECT 1
FROM TAB_B t2
WHERE t1.BR_CODE = t2.BR_CODE
AND t1.BK_CODE = t2.BK_CODE||t2.BR_CODE)
PS: BK_CODE IS THE CONCATENATION OF BK_CODE and BR_CODE
Kindly help me as I am stuck in this quagmire! Any help would be appreciated.
If the subquery returns many values which one do you want to use ?
If any you can use rownum <=1;
If you know that there is only one value use distinct
SET (V_TILL) = (SELECT TO_DATE(t2.D_DATE,'YYYYMMDD')
FROM B t2
WHERE t1.BR_CODE = t2.BR_CODE
AND t1.BK_CODE = t2.BK_CODE||t2.BR_CODE AND ROWNUM <=1)
or
SET (V_TILL) = (SELECT DISTINCT TO_DATE(t2.D_DATE,'YYYYMMDD')
FROM B t2
WHERE t1.BR_CODE = t2.BR_CODE
AND t1.BK_CODE = t2.BK_CODE||t2.BR_CODE)
above are workarounds. To do it right you have to analyze why you are getting more than one value. Maybe more sophisticated logic is needed to select the right value.
I got it working with this command:
MERGE INTO TAB_A A
USING TAB_B B
ON (A.BK_CODE = B.BK_CODE || B.BR_CODE
AND A.BR_CODE = B.BR_CODE AND B.BR_DISP_TYPE <> '0'
AND ((B.BK_CODE, B.BR_SUFFIX) IN (SELECT BK_CODE,
MIN(BR_SUFFIX)
FROM TAB_B
GROUP BY BK_CODE)))
As mentioned earlier by many, I was missing an extra condition and got it working, otherwise the above mentioned techniques work very well.
Thanks to all!

updating sql query value with select statement

I am trying to execute a query which is something like:
update table set column=(select column1 from table1);
I just want to store the value from other table to my column
but when i try my sql query it says
ERROR 1242 (21000): Subquery returns more than 1 row
definitely this means my table1 contains more than 1 row so i want to know that is there any way to store data into column from other table with multiple row.
or basically saving content of other table as a text something like
update table set column='Data in text from other table';
You probably need a correlation clause:
update table
set column = (select column1 from table1 where table.col = table1.col);
You need to decide what column(s) are used for the correlation.
it will work as i am getting your requirement.Please let me know if your requirement is other i ll make changes in query
update table_name t1
inner join table1 t2 on t1.id =t2.id
set column =column1
Your nested query returns multiple rows so you encountered this error.
Try in this way
UPDATE FirstTable
SET FirstTable.ColumnName =tbl2.ColumnName
FROM SecondTable tbl2 WHERE tbl2.Id = FirstTable.Id
There should be a common id or something that will help to find exact row.

Oracle Compare data between two different table

I have two table one is having all field VARCHAR2 but other having different type for different data.
For Example :
Table One
==========================
Col 1 VARCHAR2 UNIQUE KEY
Col 2 VARCHAR2
Col 3 VARCHAR2
===========================
Table Two
==========================
Col One VARCHAR2 UNIQUE KEY
Col Two TIMESTAMP
Col Three NUMBER
==========================
we are having one mapping table. it denotes which column of Table One has to compare with which column of Table Two.
For Example
Mapping Table
==============================
Table One Table Two
==============================
Col 1 Col One
Col 2 Col Three
Col 3 Col Two
==============================
Now with the help of UNIQUE KEY of TABLE ONE we have to find same row in TABLE TWO and compare rows column by column and get changes in data.
Currently we are using java program for comparing data row by row and column by column and getting changes between data in rows with same UNIQUE KEY. it is working fine but taking too much time as we are having 100000 records in DB.
Now my question is : is there any way i can compare data at SQL level and get changes in data?
You can do it 'manually' with a query like this: It's a lot of work, but there are only three different types of checks you need to do, so it's not very complex:
select
*
from
Table1 t1
full outer join Table2 t2 on t2.ID = t1.ID
where
-- Check ID, either record does not exist in either table.
t1.ID is null or
t2.ID = null or
-- Not nullable field can be easily compared.
t1.NotNullableField1 <> t2.NotNUllableField1 or
-- Nullable field is slightly more work.
t1.NullableField1 <> t2.NullableField1 or
(t1.NullableField1 is null and t2.NullableField1 is not null) or
(t1.NullableField1 is not null and t2.NullableField1 is null)
Another solution is to use MINUS, which is a bit like UNION, only it returns a dataset minus the records in a second dataset:
select * from Table1 t1
MINUS
select * from Table2 t2
This works only one way (which might be fine for your purpose), but you can also combine it with UNION to make it bidirectional.
select
*
from
( select * from Table1
MINUS
select * from Table2)
UNION ALL
( select * from Table2
MINUS
select * from Table1)
The output of both solutions is a bit different.
In the FULL OUTER JOIN query, the IDs will be joined and the values of the matching rows will be displayed next to each other as a single row.
In the MINUS query, the result will be presented as a single dataset. If a record does not exist in either one table, it will be displayed. If a record (ID) exists in both tables, but other fields are different, you will get both rows. So it's a bit harder to compare them.
See: http://www.techonthenet.com/oracle/minus.php

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;