Update based of 1st and 2nd table - sql

I have 3 tables.
1st table – MainTable - tableA
Have Project Name and description
A Apple
B Banana
C Carrot
2nd table - Table B
Child table :
A.10
A.20
A.30
B.10
B.20
B.30
Name of project (A, B, C) is Foreign key to table Child.
I have to update third table (table C) based on the
A …Apple
B…Banana
C…Carrot
This is Working fine with inner join.
Now when I am doing updates on code 10, 20 and 30 .. with ref to A, B and C of 10,20 and 30
It is not working.
Here is the query I wrote which is working fine to Update A, B and C
UPDATE C
SET c.[ProjectName] = a.[sysprojectname]
FROM TableC C
inner join tableA a ON c.[CostOBJProject]=a.[workpackageid]
Where c.[ProjectName] is null or c.[ProjectName]=''
So question is – I have to update table C based on value of table B with foreign key to table A.
in case I have value A and 10 in the tableC , then it should update the description in tableC .

Please check this link, this will help you
https://dev.mysql.com/doc/refman/5.7/en/update.html
I think you have problem on your syntax.
You can perform connected tables inside the UPDATE query.
UPDATE TableC, tableA
SET TableC.[ProjectName] = tableA.[sysprojectname]
Where tableA.connectcolumn = TableC.connectcolumn
AND (TableC.[ProjectName] is null or TableC.[ProjectName]='' )
With update syntax it has to be strict, therefore LEFT JOIN is not allowed on this scenario. It is equivalent to EQUI JOIN, an old style of joining.
SET clause commands the interpreter to manipulate only that column, even tho both columns were called.
With the complexity of your code you added OR logic command, would be nice to add parenthesis to properly utilize the logic.

Related

SQL update tableA.column where the column and value is in a separate table

I have tableA with the columns ID, ColumnHeader, Value.
I'm trying to update tableB where ID, and the value in tableB.ColumnHeader with tableB.Value.
Essentially, the column headers for tableB are in a column in Table A and not column headers themselves.
I'm stuck on specifying the table name. For example, how do I run this query when I only have tablename.____ where the blank is in a column in a separate table?
update tableB set table.____ .....
As seen in the screenshot below, in Table B, 4 should become 1, and 8 should become 2, and 12 should become 3. Thanks so much.
this is a example from Northwind database:
UPDATE dbo.Products
SET dbo.Products.CategoryID = c.CategoryID
FROM Products
INNER JOIN dbo.Categories c ON dbo.Products.CategoryID = c.CategoryID
I am not getting which table and column you want to update with which table and column.
also relationship is not clear.
This doesn't make sense to me. Are you trying to update table B or A? Are there like values in table B and A that you want updated?
The basic code is as shown below:
update tableb
set column id = 'value you're updating'
where column id = 'value you're looking for' --always make this unique like a key etc.

For MS Access SQL, want to use EXCEPT in Access for three columns in table1 to 1 column in table 2

I have 3 columns in table A. I am trying to design a query that will call out all the values (in the three columns) that do not apepar in the 1 column I have in table B. If it helps to make it more clear, table B is a list of currencies in ISO codes and table A is three columns of currencies being used, I am identifying all those values that are NOT using ISO codes to denote their currency.
Currently, I can't seem to get them all to match to the one column, so I made 2 more columns in table B so I can match them individually. My constraints are, I cannot change table A and I must do this in one query. What I got so far is below.
SELECT m.Currency1, i.ISO_Code, m.Currency2 , i.ISO_Code1, m.Currency3, i.ISO_Code2
FROM A AS m
LEFT JOIN B AS i
ON m.Currency=i.ISO_Code
AND m.Currency2=i.ISO_Code1
AND m.Currency3=i.ISO_Code2
WHERE i.ISO_Code is NULL
OR i.ISO_Code1 is NULL
OR i.ISO_Code2 is NULL;
I wouldn't bother making multiple columns in 'B'. I played with this in SQLFiddle and got it to work.
Something like this:
SELECT
m.Currency1, i.ISO_Code,
m.Currency2, j.ISO_Code AS ISO_Code1,
m.Currency3, k.ISO_Code AS ISO_Code2
FROM A AS m
LEFT JOIN B as i
ON m.Currency1 = i.ISO_Code
LEFT JOIN B as j
ON m.Currency2 = j.ISO_Code
LEFT JOIN B as k
ON m.Currency3 = k.ISO_Code
WHERE
i.ISO_Code IS NULL OR
j.ISO_Code IS NULL OR
k.ISO_Code IS NULL

SQL Cartesian product joining table to itself and inserting into existing table

I am working in phpMyadmin using SQL.
I want to take the primary key (EntryID) from TableA and create a cartesian product (if I am using the term correctly) in TableB (empty table already created) for all entries which share the same value for FieldB in TableA, except where TableA.EntryID equals TableA.EntryID
So, for example, if the values in TableA were:
TableA.EntryID TableA.FieldB
1 23
2 23
3 23
4 25
5 25
6 25
The result in TableB would be:
Primary key EntryID1 EntryID2 FieldD (Default or manually entered)
1 1 2 Default value
2 1 3 Default value
3 2 1 Default value
4 2 3 Default value
5 3 1 Default value
6 3 2 Default value
7 4 5 Default value
8 4 6 Default value
9 5 4 Default value
10 5 6 Default value
11 6 4 Default value
12 6 5 Default value
I am used to working in Access and this is the first query I have attempted in SQL.
I started trying to work out the query and got this far. I know it's not right yet, as I’m still trying to get used to the syntax and pieced this together from various articles I found online. In particular, I wasn’t sure where the INSERT INTO text went (to create what would be an Append Query in Access).
SELECT EntryID
FROM TableA.EntryID
TableA.EntryID
WHERE TableA.FieldB=TableA.FieldB
TableA.EntryID<>TableA.EntryID
INSERT INTO TableB.EntryID1
TableB.EntryID2
After I've got that query right, I need to do a TRIGGER query (I think), so if an entry changes it's value in TableA.FieldB (changing it’s membership of that grouping to another grouping), the cartesian product will be re-run on THAT entry, unless TableB.FieldD = valueA or valueB (manually entered values).
I have been using the Designer Tab. Does there have to be a relationship link between TableA and TableB. If so, would it be two links from the EntryID Primary Key in TableA, one to each EntryID in TableB? I assume this would not work because they are numbered EntryID1 and EntryID2 and the name needs to be the same to set up a relationship?
If you can offer any suggestions, I would be very grateful.
Research:
http://www.fluffycat.com/SQL/Cartesian-Joins/
Cartesian Join example two
Q: You said you can have a Cartesian join by joining a table to itself. Show that!
Select *
From Film_Table T1,
Film_Table T2;
No, you don't want a cartesian product where you join tables without any condition. What you are looking for is a simple self join:
insert into TableB(EntryID1, EntryID2)
select x.EntryID, y.EntryID
from TableA x
join TableA y on x.FieldB = y.FieldB and x.EntryID <> y.EntryID;
EDIT: As you want this table to be up-to-date all the time, consider a view instead of a table (only, then you could not have a manually maintained FieldD).
This should give you the 'cartesian' (its not actually a cartesian, as #ThorstenKettner mentions below - its a self join) you're after, and insert it into TableB:
INSERT INTO TableB (EntryId1, EntryId2, fieldD)
SELECT a.EntryID, b.EntryID, 'Default Value'
FROM TableA a, TableA b
WHERE a.FieldB=b.FieldB
AND a.EntryID<>b.EntryID
You don't need any relationship between the two tables for the Trigger, although I would suggest you have a foreign key relationship setup anyway, so that you never get an entry in TableB.EntryID1 or TableB.EntryID2 that doesn't have a corresponding entry in TableA.EntryID..
For the Triggers, you'd do something like this for the insert (you don't need to check TableB in this case because you know that your new TableA.EntryId doesn't exist there yet:
CREATE TRIGGER ins_tableA AFTER INSERT ON TableA
FOR EACH ROW
BEGIN
INSERT INTO TableB (EntryId1, EntryId2, fieldD)
SELECT a.EntryID, b.EntryID, 'Default Value'
FROM TableA a, TableA b
WHERE a.FieldB=b.FieldB
AND a.EntryID=NEW.EntryID
AND a.EntryID<>b.EntryID;
END;
And for the update, you could delete all the corresponding rows from TableB first, and then re-run the insert. Something like this:
CREATE TRIGGER upd_tableA AFTER UPDATE ON TableA
FOR EACH ROW
BEGIN
DELETE FROM TableB b
WHERE b.EntryId1 = NEW.EntryId
OR b.EntryId2 = NEW.EntryId;
INSERT INTO TableB (EntryId1, EntryId2, fieldD)
SELECT a.EntryID, b.EntryID, 'Default Value'
FROM TableA a, TableA b
WHERE a.FieldB=b.FieldB
AND a.EntryID=NEW.EntryID
AND a.EntryID<>b.EntryID;
END;
None of this is tested I'm afraid, but hopefully it'll put you on the right track..

Delete rows present in other table

I have two tables A and B containing many columns, two of which in use are SKU and Typedesc.
I created a table C by joining A and B on sku and typedesc
create table C as
select A.*
from A inner join
B
on A.sku=B.sku and trim(A.typedesc)=trim(B.typedesc)
C has approx. 130,000 records
Now I want to delete the rows in A which are present in C
delete from A A1
where exists (select 1
from C c1
where A1.sku=c1.sku and trim(A1.typedesc)=trim(c1.typedesc)
)
It says 145,000 rows deleted.
Where did the extra 15,000 rows came from? Is there something wrong with my delete query? So when I join two tables, C should also have 145,000 but instead it has only 130,000!! why is this so? A or B does not contain any primary key.
Even if i delete B from A directly, the number of rows deleted remains 145,000.
delete from A A1
where exists (select 1
from B b1
where A1.sku=b1.sku and trim(A1.typedesc)=trim(b1.typedesc)
)
The EXISTS looks alright, but without seeing which rows are being deleted it's hard to tell what the problem is, and I don't want to review 145,000 rows any more than you do :)
Try this alternative and see if it makes any difference:
DELETE FROM A
WHERE (SKU, TRIM(TypeDesc)) IN (SELECT SKU, TRIM(TypeDesc) FROM B)

SQL Query - Ensure a row exists for each value in ()

Currently struggling with finding a way to validate 2 tables (efficiently lots of rows for Table A)
I have two tables
Table A
ID
A
B
C
Table matched
ID Number
A 1
A 2
A 9
B 1
B 9
C 2
I am trying to write a SQL Server query that basically checks to make sure for every value in Table A there exists a row for a variable set of values ( 1, 2,9)
The example above is incorrect because t should have for every record in A a corresponding record in Table matched for each value (1,2,9). The end goal is:
Table matched
ID Number
A 1
A 2
A 9
B 1
B 2
B 9
C 1
C 2
C 9
I know its confusing, but in general for every X in ( some set ) there should be a corresponding record in Table matched. I have obviously simplified things.
Please let me know if you all need clarification.
Use:
SELECT a.id
FROM TABLE_A a
JOIN TABLE_B b ON b.id = a.id
WHERE b.number IN (1, 2, 9)
GROUP BY a.id
HAVING COUNT(DISTINCT b.number) = 3
The DISTINCT in the COUNT ensures that duplicates (IE: A having two records in TABLE_B with the value "2") from being falsely considered a correct record. It can be omitted if the number column either has a unique or primary key constraint on it.
The HAVING COUNT(...) must equal the number of values provided in the IN clause.
Create a temp table of values you want. You can do this dynamically if the values 1, 2 and 9 are in some table you can query from.
Then, SELECT FROM tempTable WHERE NOT IN (SELECT * FROM TableMatched)
I had this situation one time. My solution was as follows.
In addition to TableA and TableMatched, there was a table that defined the rows that should exist in TableMatched for each row in TableA. Let’s call it TableMatchedDomain.
The application then accessed TableMatched through a view that controlled the returned rows, like this:
create view TableMatchedView
select a.ID,
d.Number,
m.OtherValues
from TableA a
join TableMatchedDomain d
left join TableMatched m on m.ID = a.ID and m.Number = d.Number
This way, the rows returned were always correct. If there were missing rows from TableMatched, then the Numbers were still returned but with OtherValues as null. If there were extra values in TableMatched, then they were not returned at all, as though they didn't exist. By changing the rows in TableMatchedDomain, this behavior could be controlled very easily. If a value were removed TableMatchedDomain, then it would disappear from the view. If it were added back again in the future, then the corresponding OtherValues would appear again as they were before.
The reason I designed it this way was that I felt that establishing an invarient on the row configuration in TableMatched was too brittle and, even worse, introduced redundancy. So I removed the restriction from groups of rows (in TableMatched) and instead made the entire contents of another table (TableMatchedDomain) define the correct form of the data.