ORACLE SQL - updatestatement for max technical key per ID - sql

I need to write an update statement for a table of mine.
The table contains a technical key and a customer ID.
I need to update a field in this table by raising the field with +1, but only for the fields where the technical key is at the max value for that specific customer ID.
At first I tried to write this with how I usually do it on MSSQL:
UPDATE a
SET a.VERSION_CHECK = (a.VERSION + 1)
FROM customers a
WHERE a.technical_key = (SELECT MAX(b.technical_key)
FROM customers b
WHERE a.customer_id = b.customer_id
)
I've since been trying to work with a WHERE EXISTS clause in the syntax of the SQL used in Oracle, but I can't seem to figure out how to work the MAX technical key in there correctly, so that only those rows are updated in the table. Anyone got any input please?

You can use a use a correlated subquery:
UPDATE customer c
SET VERSION_CHECK = VERSION + 1
WHERE c.technical_key = (SELECT MAX(c2.technical_key)
FROM customers c2
WHERE c2.customer_id = c.customer_id);

Related

Copying a column from one table to another

I have photos table onto which I'm trying to insert a new column from another table by filtering data with a WHERE clause. Here is the query I'm trying to execute:
ALTER TABLE photos ADD COLUMN new_count BIGINT;
INSERT INTO photos (new_count)
SELECT c.cnt
FROM c
WHERE
c.created = photos.created;
But in the result I am getting an error:
Error : ERROR: invalid reference to FROM-clause entry for table "photos"
LINE 5: c.created = photos.created
How can avoid the error and copy the column?
I'm using PostgreSQL 9.4.
Join in the referenced table c with a FROM clause.
UPDATE photos p
SET new_count = c.cnt
FROM c
WHERE c.created = p.created
AND c.cnt IS NOT NULL; -- optional, depends on additional circumstances
Details in the manual.
Correlated subqueries (like demonstrated by #Andomar) are generally slower, and they also have a side effect that's typically undesirable:
If no matching row is found in c, the UPDATE proceeds regardless and new_count is set to NULL. This happens to be not wrong in this particular case (since the column is NULL by definition of the case). It's still pointless extra cost. Often, the effect is actively harmful, though.
The added condition AND c.cnt IS NOT NULL further avoids empty updates if the new value is no different from the old. Useless if c.cnt cannot be NULL. It's the simplified form of the generic check: AND c.cnt IS DISTINCT FROM p.new_count. Details (last paragraph):
How do I (or can I) SELECT DISTINCT on multiple columns?
Use insert to add rows to a table, and update to change existing rows. Here's an example of how to update a column in photos based on a link to the c table:
update photos p
set new_count =
(
select cnt
from c
where c.created = p.created
)

Updated SQL Field based on Conditions in a Related Table

I am new to SQL and despite hours of searching, cannot figure out the SQL query to update records in my members table, based on conditions in my payments table. I'm very confused whether I use a JOIN (and if so what kind) or a Subquery?
Here's what I have so far:
UPDATE wp_mcra_members
SET wp_mcra_members.dues_paid = 1
JOIN wp_mcra_payments ON wp_mcra_payments.member = wp_mcra_members.ID
WHERE wp_mcra_payments.year_paid = '2013' and wp_mcra_payments.reason = 'Dues';
I want the databased to search for any records in the Payments table that meet my conditions of being year 2013 and labeled Dues. Then I want the Members table to update the field dues_paid based on any found records matching those conditions, where the Member ID = Payments Member
The syntax for an update with a join varies by database. Here is generic syntax using a subquery in the where clause:
UPDATE wp_mcra_members
SET dues_paid = 1
where wp_mcra_members.id in (select wp_mcra_payments.member
from wp_mcra_payments
WHERE wp_mcra_payments.year_paid = '2013' and
wp_mcra_payments.reason = 'Dues'
) ;
The syntax you supplied looks like it would work if you are using SQL Server. Oracle does not support JOINs with UPDATE, instead look into using MERGE or Gordon's answer would also work there.
Assuming however you are using MySQL, a JOIN in the UPDATE statement would probably have a better performance than using IN:
UPDATE wp_mcra_members
JOIN wp_mcra_payments ON wp_mcra_payments.member = wp_mcra_members.ID
SET wp_mcra_members.dues_paid = 1
WHERE wp_mcra_payments.year_paid = '2013'
and wp_mcra_payments.reason = 'Dues';

Multiple Query Writing in Single Query

I have two tables in Database , I need to select a field from one table and update it in another table with a condition where id is same .. Is it Possible to write in single query ???
This should work for you:
update storage
set storage.email = (select register.email
from register
where register.id = storage.id)
Yeah it is, you could do this for example:
UPDATE Origin SET DesiredColumn = NewValue
FROM Origin
JOIN NewTable ON Origin.Id = NewTable.Id
And guess the column names were like DesiredColumn in the updating table and NewValue in the table that holds the new value.
Yes, this is possible, although the syntax depends on the type of SQL you are using.
Here is an example for T-SQL (for Microsoft SQL Server)
UPDATE
S
SET
Email = R.Email
FROM
dbo.Register R
INNER JOIN dbo.Storage S
ON S.RegisterID = R.RegisterID

Determining best method to traverse a table and update another table

I am using Delphi 7, BDE, and Interbase (testing), Oracle (Production).
I have two tables (Master, Responses)
I need to step through the Responses table, use its Master_Id field to look it up in Master table (id) for matching record and update a date field in the Master table with a date field in the Responses table
Can this be done in SQL, or do i actually have to create two TTables or TQueries and step through each record?
Example:
Open two tables (Table1, Table2)
with Table1 do
begin
first;
while not EOF do
begin
//get master_id field
//locate in id field in table 2
//edit record in table 2
next;
end;
end;
thanks
One slight modification to Chris' query, throw in a where clause to select only the records that need the update. Otherwise it will set the rest of the dates to NULL
UPDATE Master m
SET
m.date = (SELECT r.date FROM Reponses r WHERE r.master_id = m.id)
WHERE m.id IN (SELECT master_id FROM Responses)
Updated to use aliases to avoid confusion which col comes from which table.
This is not ready made, copy-past'able query as UPDATE syntax differs from database to database.
You may need to consult your database sql reference for JOIN in UPDATE statement syntax.
When there are multiple responses to same master entry
UPDATE Master m
SET m.date = (
SELECT MAX(r.date) FROM Reponses r WHERE r.master_id = m.id)
WHERE m.id IN (SELECT master_id FROM Responses)
I used MAX() you can use whatever suits your business.
Again invest some time understanding SQL. Its hardly a few days effort. Get PLSQL Complete reference if you are into Oracle
Try this SQL (changing names to fit your situation)
UPDATE Master m
SET date = ( SELECT date FROM Responses WHERE id = m.id )

Update Query from a Lookup Query

I have a spreadsheet that I am converting to an Access DB. I have a column of typed out customer names that I want to replace with the appropriate customer number from our accounting system.
I have created a table with the customer info, and a query that shows what ID needs to be inserted into the source data. What I'm looking for is:
UPDATE tblStarting_Data
SET CustomerID=x
WHERE TEMPCustomer=y
Where X and Y come from qryIDPerCustomer.
Can I use a loop? How do I reference another query?
Another possibility in MS Access (object names borrowed from Tomalak answer):
UPDATE tblStarting_Data, qryIDPerCustomer
SET tblStarting_Data.CustomerID=qryIDPerCustomer.CustomerID
WHERE tblStarting_Data.TEMPCustomer=qryIDPerCustomer.CustomerName
I think a JOIN will help you:
UPDATE
tblStarting_Data AS sd
INNER JOIN qryIDPerCustomer AS qc ON sd.TEMPCustomer = qc.CustomerName
SET
sd.CustomerID = qc.CustomerID;
This can be expressed as a correlated sub-query as well (though the join syntax is preferable):
UPDATE
tblStarting_Data
SET
CustomerID = (
SELECT CustomerID
FROM qryIDPerCustomer
WHERE CustomerName = tblStarting_Data.TEMPCustomer
)
No need for a loop, both statements will update all records in tblStarting_Data in one step.