How to us a Subquery to Update Multiple Column Values in SQL? - sql

My ultimate goal is to be able to update multiple column values from one table to another without having to write each one out.
I found the following on IBM's site the indicated how to do it (Link)
UPDATE items
SET (stock_num, manu_code, quantity) =
( (SELECT stock_num, manu_code FROM stock
WHERE description = 'baseball'), 2)
WHERE item_num = 1 AND order_num = 1001;
UPDATE table1
SET (col1, col2, col3) =
((SELECT MIN (ship_charge), MAX (ship_charge) FROM orders), '07/01/2007')
WHERE col4 = 1001;
I took this and attempted to create it on my end, but I keep getting an "Incorrect syntax near '('" error.
UPDATE XX__JeremyTempTable2
SET (OP__DOCID, SexualPrefCode) =
(SELECT OP__DOCID, SexualPrefCode FROM FD__CLIENTS
WHERE CLIENTKEY = 726148)

For MS Sql server your query will be
UPDATE XX__JeremyTempTable2
SET OP__DOCID = FD__CLIENTS.OP__DOCID,
SexualPrefCode = FD__CLIENTS.SexualPrefCode
FROM FD__CLIENTS
WHERE FD__CLIENTS.CLIENTKEY = 726148
With such errors you need check manual
Edit Changed to your target query.

You have to set each variable separately:
UPDATE XX__JeremyTempTable2
SET OP__DOCID = (SELECT OP__DOCID FROM FD__CLIENTS WHERE CLIENTKEY = 726148) ,
SexualPrefCode = (SELECT SexualPrefCode FROM FD__CLIENTS WHERE CLIENTKEY = 726148)

Related

PLSQL - Update statement with variable

I am currently trying to write an update statement using a variable (which will be expanded to use multiple variables later on).
Currently I have the following statement (altered for posting here), but I am running into an error and I don't immediately see the mistake I am making:
DECLARE
v_var1 table1.CY_VALUE % TYPE;
BEGIN
SELECT SUM(Column1 + Column2)
INTO v_var1
FROM table2
WHERE survey_ID = 1 AND Active_Flag = 1
GROUP BY SURVEY_ID;
UPDATE table1
SET CY_VALUE = v_var1
WHERE SURVEY_ID = 1 AND KPI_ID = 1;
END;
This is the error I am receiving:
SQL Error [6550] [65000]: ORA-06550: line 15, column 1:
PLS-00103: Encountered the symbol "END" when expecting one of the following:
:= . ( # % ;
What do I need to alter in order to get this to work in this example?
Or are there better ways to write the update for table 1, containing a sum from table 2?
There is nothing obviously wrong with your code. But why not just use a correlated subquery and dispense with the variable -- and the PL/SQL?
UPDATE table1 t1
SET CY_VALUE = (SELECT SUM(t2.Column1 + t2.Column2)
FROM table2 t2
WHERE t2.survey_ID = t1.survey_ID AND
t2.Active_Flag = 1
)
WHERE SURVEY_ID = 1 AND KPI_ID = 1;
Although not related to your error, the GROUP BY in the first query is also misleading. An aggregate query with a GROUP BY can return any number of rows -- including 0. Instead, just lead out the GROUP BY:
SELECT SUM(Column1 + Column2)
INTO v_var1
FROM table2
WHERE survey_ID = 1 AND Active_Flag = 1;
The WHERE clause filters down to the survery_ID you want and without the GROUP BY this query always returns exactly one row.

How do I UPDATE from a SELECT in Informix?

I'm trying to do an update using data from another table. I've tried this answer (the second part), but it is not working for me. I'm receiving a generic error message of syntax error.
I've also tried this solution and received a syntax error message too.
If I try to update just one column, it works:
UPDATE dogs
SET name =
(
SELECT 'Buddy'
FROM systables
WHERE tabid = 1
);
But I need to update multiples columns. Unfortunately, this is not working:
UPDATE dogs
SET (name, breed) =
(
SELECT 'Buddy', 'pug'
FROM systables
WHERE tabid = 1
);
Informix version is 12.10.FC8
You are missing 1 more set of parentheses around the subquery.
From the Informix manual:
The subquery must be enclosed between parentheses. These parentheses
are nested within the parentheses that immediately follow the equal (
= ) sign. If the expression list includes multiple subqueries, each subquery must be enclosed between parentheses, with a comma ( , )
separating successive subqueries:
UPDATE ... SET ... = ((subqueryA),(subqueryB), ... (subqueryN))
The following examples show the use of subqueries in the SET clause:
UPDATE items
SET (stock_num, manu_code, quantity) =
(
(
SELECT stock_num, manu_code
FROM stock
WHERE description = 'baseball'
),
2
)
WHERE item_num = 1 AND order_num = 1001;
UPDATE table1
SET (col1, col2, col3) =
(
(
SELECT MIN (ship_charge), MAX (ship_charge)
FROM orders
),
'07/01/2007'
)
WHERE col4 = 1001;
So in order for your update to be accepted by Informix it has to be:
UPDATE dogs
SET (name, breed) =
(
(
SELECT 'Buddy', 'pug'
FROM systables
WHERE tabid = 1
)
);

Update date column from min date in another column in the same table

I need to update a field called "FirstPayment" with the date from another field in the same table.
Here is the code:
UPDATE R1
SET R1.FirstPayment = (select min(r1.effective_date) where R1.amount>0)
from CTTC_RentalCarPayments R1, CTTC_RentalCarPayments R2
where r1.id=r2.id
This results in "An aggregate may not appear in the set list of an UPDATE statement"
I know I am missing something simple here.
I also know the FirstPayment field isn't necessary because I could get that date in a query but the application I am feeding this data too needs it in this column.
Use window functions:
with toupdate as (
select r.*,
min(case when r1.amount > 0 then r.effective_date end) over (partition by id) as new_effective_date
from CTTC_RentalCarPayments r
)
update toupdate
set FirstPayment = new_effective_date;
You could set value of the field you want to get to a variable and then update the field to that variable:
Declare #firstPayment datetime;
Set #firstPayment = (select min(r1.effective_date) from r1 where R1.amount>0);
Declare #firstPaymentID int;
Set #firstPaymentID = (select id from r1 where #firstPayment = FirstPayment);
UPDATE r1
SET FirstPayment = #firstPayment where Id = #firstPaymentID;
Let me know if this helps. It's not a recursive CTE but it might work too.

SQL server update table with missing values

I have 2 similar tables, one with all the data and the other contains a subset of the first. Every 2-3 days I need to insert in the second table the missing values, and I use this code
INSERT INTO [SRVDB2].[dbt].[curve].[curve_value]
SELECT *
FROM [SRVDB1].[dbt].[curve].[curve_value] as DB01
WHERE TargetDate >= '20150505'
and NOT EXISTS (SELECT *
FROM [SRVDB2].[dbt].[curve].[curve_value] as DB02
WHERE DB02.TargetDate = DB01.TargetDate
and DB02.[Hour] = DB01.[Hour]
and DB02.[id_Mkt] = DB01.[id_Mkt]
and DB02.[Price] = DB01.[Price]
and DB02.VoSe = DB01.VoSe
and DB02.VoBu = DB01.VoBu
)
It always worked but now I have some rows with NULL in column VoSe or VoBu and those values are not inserted correctly (even if executing only the SELECT statement seems to return all the differences). How can I handle these?
Add explicit check for NULL for both of these columns:
INSERT INTO [SRVDB2].[dbt].[curve].[curve_value]
SELECT *
FROM [SRVDB1].[dbt].[curve].[curve_value] as DB01
WHERE TargetDate >= '20150505'
and NOT EXISTS (SELECT *
FROM [SRVDB2].[dbt].[curve].[curve_value] as DB02
WHERE DB02.TargetDate = DB01.TargetDate
and DB02.[Hour] = DB01.[Hour]
and DB02.[id_Mkt] = DB01.[id_Mkt]
and DB02.[Price] = DB01.[Price]
and ((DB02.VoSe IS NULL AND DB01.VoSe IS NULL) OR DB02.VoSe = DB01.VoSe)
and ((DB02.VoBu IS NULL AND DB01.VoBu IS NULL) OR DB02.VoBu = DB01.VoBu)
)
#dotnetom's answer (+1) should work for your problem. However, making some assumptions on the problem you describe, I suspect the following would work just as well:
INSERT INTO [SRVDB2].[dbt].[curve].[curve_value]
SELECT *
FROM [SRVDB1].[dbt].[curve].[curve_value]
WHERE TargetDate >= '20150505'
EXCEPT SELECT *
FROM [SRVDB2].[dbt].[curve].[curve_value]
Use ISNULL to handle the NULL values.
NOTE: Use some random value in ISNULL function which will not come in those two columns. For example i have kept 'AAA'
SELECT *
FROM [SRVDB1].[dbt].[curve].[curve_value] as DB01
WHERE TargetDate >= '20150505'
and NOT EXISTS (SELECT *
FROM [SRVDB2].[dbt].[curve].[curve_value] as DB02
WHERE DB02.TargetDate = DB01.TargetDate
and DB02.[Hour] = DB01.[Hour]
and DB02.[id_Mkt] = DB01.[id_Mkt]
and DB02.[Price] = DB01.[Price]
and ISNULL(DB02.VoSe,'AAA') = ISNULL(DB01.VoSe,'AAA')
and ISNULL(DB02.VoBu,'AAA') = ISNULL(DB01.VoBu,'AAA')
)

SQL Update - Cant specify target table in select

I have the following table
#key | #value
colour | red
weather | blue
Now I want to update the value of the row with the key colour to be the value of the row with the key weather. So I am doing:
UPDATE table_name
SET value = (SELECT value FROM table_name WHERE key = "weather")
WHERE key = "colour";
But this update gives me following error message:
You can't specify target table for update in FROM clause
How can I do that query without error?
This may be because it may be the case that the select query returns more than one value for the column value
UPDATE table_name
SET value = (SELECT max(value) FROM table_name WHERE key = "weather")
WHERE key = "colour";
or
UPDATE table_name
SET value = (SELECT value FROM table_name WHERE key = "weather" limit 1)
WHERE key = "colour";
You may try to change it like this by replacing the instance of table_name in the sub-query with (SELECT * FROM table_name):
UPDATE table_name
SET table_name.A =
(
SELECT B
FROM (SELECT * FROM table_name) AS something
INNER JOIN ...
)
Also check How to select from an update target in MySQL
You don’t want to just SELECT * FROM table in the subquery in real
life; I just wanted to keep the examples simple. In reality you should
only be selecting the columns you need in that innermost query, and
adding a good WHERE clause to limit the results, too.
EDIT:-
As you have already commented that but I have answered above to use the temporary table like this:-
UPDATE table_name
SET value = (SELECT value FROM (SELECT value FROM table_name WHERE key="weather") AS x)
WHERE key="colour"
you might try this if your sql supports 'LIMIT'
UPDATE table_name SET value = (SELECT value FROM table_name WHERE key = "weather" LIMIT 1 ) WHERE key = "colour";
UPDATE table_name
SET colour ='red',weather =blue
WHERE column_name = some_value;
It won't work that way. You can't have a read and a write query at the same time for the same table. With two different tables it will work.
UPDATE `table` SET value = (SELECT value FROM `Table_b` WHERE `other_value` = 'xy' LIMIT 1) WHERE `key` = 'colour'