SQL Update - Using Multiple Table Joins - sql

Wondering if anyone can point me in the right direction please.
I Have 3 tables...
Table A -
Code, Cost1, Cost2, Cost3
Table B -
Code, ID
Table C -
ID, Price
Basically I need to update the Price Field on Table C with (Cost1+Cost2+Cost3)
from Table A.
There is no direct link between the 2 tables, but A is linked to B via Code and B is linked to C via ID.
I can write a query to display Price and the Total Cost but can't get my head around how to do the Update.
Any pointers would be extremely welcome
Thanks
Andrew

UPDATE TC
SET Price=(TA.Cost1+TA.Cost2+TA.Cost3)
FROM TableA TA
INNER JOIN TableB TB ON TA.Code=TB.Code
INNER JOIN TableC TC ON TC.ID=TB.ID
I prefer writing my more complicated joins out first and then simply updating the alias. As you can see in the example, you could comment out the top two lines and simply put in a SELECT TC.ID,TA.Cost1+TA.Cost2+TA.Cost3 and see exactly what would change.

Related

How to select only rows that are not in another table without getting data of the other table - PLSQL

Im trying to SELECT all rows from one table with a specific condition. Im using Oracle PLSQL.
I have two tables:
Books
id
name
Page
id
words
book_id
One book can have multiple pages.
I want to find all books that don't have any page with 50 words.
The only solution I've found is to make a Left Outer Join and then filter by nulls.
Select * from Books b
LEFT OUTER JOIN Page p on b.id = p.book_id and p.words = 50
where p.words is null
I think its not a good solution, but it works, do you know any other way to do that?
I don't want to take any information about Pages. If I make a normal join and then I apply the condition I get N rows for a Book, and I only want to get 1 row for each Book
Thanks.
You could adjust your select so it is only b.*.
Possibly a more common alternative is not exists:
select b.*
from Books b
where not exists (select 1
from Page p
where b.id = p.book_id and p.words = 50
);
The two methods should have similar performance characteristics.

Joining three tables clarification

This isn't a question I need a direct answer to, I Just need to know how, from a philosophical point of view, how many tables I would need to join.
Say I have 3 tables :
TableA :
Account_Number | Name | Address
TableB :
Account_Number | Occupation | Salary
TableC :
Account_Number | Model | Make
These tables all have a column in common. If I was to join these tables together to get a the columns in each table that has a matching account number, i would do an inner join to return only records that are matching.
in the query, I would have something like :
SELECT T1.Name, T1.Address, T2.Occupation, T2.Salary, T3.Model, T3.Make
FROM TableA T1
INNER JOIN TableB T2 ON T1.Account_Number=T2.Account_Number
INNER JOIN TableC T3 ON T2.Account_Number=T3.Account_Number /Do I need to join T3 to T1 or is this handled by having T1 and T2 joined together?
WHERE ??.AccountNumber=1234123412341234 /Would any Table work in the WHERE clause here since we are all looking for the same account_number in each table?
SELECT T1.Name, T1.Address, T2.Occupation, T2.Salary, T3.Model, T3.Make
FROM TableA T1
INNER JOIN TableB T2 ON T1.Account_Number=T2.Account_Number
INNER JOIN TableC T3 ON T2.Account_Number=T3.Account_Number /Do I need to join T3 to T1 or is this handled by having T1 and T2 joined together?
WHERE T1.AccountNumber=1234123412341234
Inner join will return only records which are present in the table you are joining ,. So in your select your use TableA so in where clause you should use T1.AccountNumber
For more information please look this link http://www.sql-join.com/
There are a few things to consider with respect to your data model. For example
o What is the relationship between these tables? Is there one? Is the fact that there is an Account_Number column just a coincidence
o Assuming there is a relationship, what is the cardinality? For example, for any given row in Table A, how many corresponding rows are there in Table B; 0, 1 or more than one. Similarly from Table B to table A; and similarly between Tables B and C.
o. Depending on the meaning of these relationships, you could find yourself in a situation called a "fan trap". This is a situation where you have a fanning out of relationships:
B
/ \
/ \
A C
It easier to describe with an Example.
Lets say:
A is a table of Sales Reps
B is a table of Branches
C is a table of Accounts
So each Sales Rep works in one Branch (cardinality=1), and each Branch has 1 or more Sales Rep ( cardinality=Many )
Each Branch handles many Accounts, and each Account is held at one Branch
This is a perfectly valid data model
However, from this data model, if you want to find out which sales rep handles which account, you cannot. This is the so called Fan trap. In this particular example, you would probably solve this be having a relationship directly between Sales Rep and Accounts; even though it may look redundant.
So I know this is a long answer to your question, but it elaborates on the short answer, which is "It depends" :)
BobC is right concerning semantics, it depends.
Syntactically, your example is fully correct and just how I would do it too. Joining applies to just 2 objects/result sets and both have to be in the condition when you don't want a cross join. Furthermore it doesn't matter which of the identically account# columns from the first join you use in the second join.
As for the WHERE condition, if only one of the tables got an Index or Partionkey, use that one. Else, use the table on which the WHERE statement gives you the fewest rows.
Joining often benefits from starting with the smallest tables/result sets. Although Oracle will optimize your statement respecting the gathered statistics anyway.

SQL INNER JOIN without linked column

I have an UltraGrid displaying customer information in it. The way the database is set up, there are 2 tables. Customers and Customer_Addresses. I need to be able to display all of the columns from Customers as well as Town and Region from Customer_Addresses, but I'm under the impression that I'd need Town and Region columns in the Customer table to be able to do this? I've never used an INNER JOIN before so I'm not sure if this is true or not, so can anybody give me pointers on how to do this, or if I need the matching columns or not?
Does it even require an INNER JOIN, or is there an alternative way to do this?
Below are the design views of both of the tables - Is it possible to display Add4 and Add5 from Customer_Addresses with all of Customers?
As long as you have another key column you can use to link the tables (ex. ID_Column), it is better that you use LEFT JOIN.
Example:
SELECT c.col1, ... , c.colN, a.town, a.region FROM Customers c
LEFT JOIN Customer_Addresses a ON a.ID_Column = c.ID_Column
In order to clarify how JOIN types work, look at this picture:
In our case, using a LEFT JOIN will take all information from the Customers table, along with any found matching (on ID) information from Customer_Addresses table.
First of all you need some column in common in two tables, all what you have to do is:
CREATE TABLE all_things
AS
SELECT * (or columns that you want to have in the new table)
FROM Costumers AS a1
INNER JOIN Customer_Addresses AS a2 ON a1.column_in_common = a2.column_in_common
The point is what kind of join do you want.
If you can continue the process without having information in table Costumers or in table Customer_Addresses maybe you need OUTER JOIN or other kind of JOIN.

Update a field from one table to another, involving a 3 table join

I have a table I need to update the price field in. I need to update this field from a different price field from a different table. The only way I can get to the required table for the update is by joining another table into this query.
So in all I need to join 3 tables in the update.
Table A has the price field that needs to be updated. In this table I have the foreign key of the product.
Table A structure
-PK_TABLE_A,
-FK_TABLE_B,
-ITEM_COST,
-ITEM_PRICE (needs to be updated from Table C)
Table B is the product table which has the PK of the product. This table is used to access Table C.
I also need to filter Table B to only update a certain stock type.
Table B structure
-PK_TABLE_B,
-FK_TABLE_C,
-DESCRIPTION,
-QUANTITY,
-ITEM_TYPE (a string that needs to be added in where clause to only update records with certain type).
Table C has a foreign key back to Table B. It also contains the price field that I need to use to update the price field in table A
Table C structure
-PK_TABLE_C,
-FK_TABLE_B,
-PRICE (this is the field that I need to use to update the price field in table A)
-USED_DATE,
-ID
The DBMS I am using is Firebird.
I have tried to use sub queries to no avail. I regularly use a sub-select when using two tables to update, so something like
UPDATE table1 AS t1
SET t1.FK = (select table2.PK
FROM table2 INNER JOIN
table1
ON table2.FK = table2.PK
WHERE table2.name = t1.name)
I'm just struggling to use the same technique with a 3rd table incorporated.
I am not even sure if this is the correct way to go about this situation. I have looked on google, but most examples I have come across don't utilise the 3rd table.
Any help would be appreciated.
**edited to included more detail on table structure.
are you able to show us the table structures in more detail?
if both tableA and tableC have a foreign key that points back to tableB I don't think you need to include a three table join. you just need to
update tableA set ITEM_PRICE = SELECT(PRICE FROM TableC WHERE
TableA.FK_TABLE_B = TableC.FK_TABLE_B;
unless I'm missing something?
edited to reflect a better understanding of the problem
alright, I think I've got it this time:
update tableA set price =
(select price from tableC where tableA.fk_tableB = tableC.fk_tableB) where
(Select item_type from tableB where tableB.pk_tableB = tableA.fk_tableB) =
'$itemTypeVariable';
edited again with a better understanding of the problem

How to know the number difference between 2 tables in sql

I really need to know the query to display another field which is I want to name it as "number_difference" between 2 tables that required a numeric (in this case as a quantity).
I have 2 tables that totally same, let say, I modify the value from table A so some value in table A different with table B. And I want to join it into 1 table that display rows that some values were modified. I already get the result by this query :
**
select a.T1, a.T2 a.T3 ... from A where not exists (select * from B
where a.T1=b.T1 and a.T2=b.T2 and a.T3=b.T3)
**
This query works well. But, I want to add more field, the difference number between this 2 field (quantity) in 2 different tables. So let say, a.T3 and b.T3 are quantities. And want to display it as "number_difference" next to field (T2) which I display. Sorry I can't post images, they say I need at least 10 reputation to post. Please help me master, how can I make it everytime I use join/inner join it always display soo many rows that I only need the rows which a value from 1 table I have modified.
Thanks in advance.
You can get something like this
Select * From A Where A.id not in( Select Id from B)
or
Select A.* From A left join B on A.id = B.id Where A.id <> B.id
If you are specifically targeting a situation with two identical tables, where one underwent UPDATE operations only (no INSERT), and you want to identify those records which were modified, then:
select a.* from a, b where a.id=b.id and ( a.c1!=b.c1 or a.c2!=b.c2)