Updating a table using a different table - sql

This is probably very simple but as I am an SQL noobie I do not want to get this wrong and destroy our database.
I am looking at updating a table based on what is in another table. in one table we have a list of users, the form they are in and their tutor. When the form is updated on the front end it does not change the tutor to the one who is related with that form. For example, we have changed the form to the new ones and the tutors below should now read Tom, Dick and Harry respectively:
Table 1
user | form | tutor
---------------------------------
a | 10Tom | Bill
b | 11Dick | Paul
c | 9Harry | Dave
We have another table which links up the respective forms to the correct tutors:
Table 2
form | tutor
-----------------------
10Tom | Tom
11Dick | Dick
9Harry | Harry
I am thinking the code should look like this, but I do not know if JOIN works in this situation:
UPDATE Table1
LEFT OUTER JOIN Table2
ON Table1.Form = Table2.Form
SET Table1.Tutor = Table2.Tutor
WHERE Table1.Form = Table2.Form
Can anyone give me some insight whether this will work? I have backed up the database so hopefully if I do break something I can recover it.
Thanks
Rob

In MySQL, you can express this as:
UPDATE Table1 t1 JOIN
Table2 t2
ON t1.Form = t2.Form
SET t1.Tutor = t2.Tutor;
In SQL Server or Postgres, you could do:
UPDATE Table1 t1 JOIN
SET t1.Tutor = t2.Tutor
FROM Table2 t2
WHERE t1.Form = t2.Form;
In any database, you should be able to do:
UPDATE Table1 JOIN
SET Tutor = (SELECT t2.Tutor
FROM Table2 t2
WHERE table1.Form = t2.Form
)
WHERE EXISTS (SELECT 1
FROM Table2 t2
WHERE table1.Form = t2.Form
);

this should work. I am assuming the requirement needs a left outer join.
UPDATE Table1
SET Table1.Tutor = Table2.Tutor
from Table2
where Table1.Form = Table2.Form;

You didn't specify the backend you are using but that syntax doesn't look right. Instead do it like:
UPDATE Table1
SET Table1.Tutor = Table2.Tutor
from table2
WHERE Table1.Form = Table2.Form;

Update Table1
SET tutor = t2.tutor
From Table1 t1
JOIN Table2 t2
on t1.form = t2.form

Related

Linking two Columns in the same table

I have the following columns in my table:
Title | Title Root
-------|--------------
A | null
B | A
C | D
D | null
E | null
F | E
I need to be able to have my query see that rows like B,C, and F have a value in Title_Root and display the corresponding title of that title_root. For example: B has Title_root = A. So then display the Title A. I don't want it to display B's title though.
I hope this makes sense. I just started doing queries.
Looks like a simple outer join:
select t1.title,
t2.title_root
from the_table t1
left join the_table t2 on t2.title_root = t1.title
Or if you only want to see one title:
select coalesce(t2.title_root, t1.title) as title
from the_table t1
left join the_table t2 on t2.title_root = t1.title
It seems like a simple update statement should do the trick:
UPDATE Table
SET title = title_root
WHERE title_root is not null
Hope this helps.

SQL condition for a join

I've created an SQL query (Oracle) that is a join of 2 tables, and this table has entries related to users joining or leaving a particular instance.
So, let's say that the table looks something like:
+------------+--------+
| User_ID | State |
+------------+--------+
| 101 | Joined |
+------------+--------+
| 102 | Joined |
+------------+--------+
| 101 | Left |
+------------+--------+
As you can see, user 101 Joined, but then left. Is it possible to somehow specify that in case user left, then all entries related to this user are removed from the table (user ID is unique), but in case there is only entry saying that user Joined, then user will stay in the table?
I am new to SQL, my apologies if the question lacks some details, please feel free to ask for clarification.
To remove the records pertaining to users that have left, you might try the following:
DELETE FROM mytable m1
WHERE EXISTS ( SELECT 1 FROM mytable m2
WHERE m2.user_id = m1.user_id
AND m2.state = 'Left' );
Alternately (this might make things a bit more clear):
DELETE FROM mytable m1
WHERE m1.user_id IN ( SELECT m2.user_id
FROM mytable m2
WHERE m2.state = 'Left' );
Hope this helps.
You can get the list of ID that has the State "Left" and then delete those IDs
DELETE FROM tablename
WHERE user_id IN (SELECT user_id
FROM tablename
WHERE state = "left")
You can do something like this:
select t.*
from t
where not exists (select 1 from t t2 where t2.id = t.id and t.state = 'Left');
You can easily turn this to a delete:
delete t
where exists (select 1 from t t2 where t2.id = t.id and t.state = 'Left');

Creating a SQL column based on the value of another column in the same table

I must not be using the right Google foo to find the correct answer.
I have a table that looks like the following:
ID Parent  Status   Name
1              NULL     0              Root 2             1              0              Group 1
3             6              400         WINXP32
4              2              400         WIN7
5              2              400         WIN2K8
6              1              0              Group 2
The 'name' column contains both group names and machine names. Groups have a 'Status' of 0.
How would I create a SQL statement to display (not modify the database) a column called 'Group' based on the logic that the 'Parent' column holds the 'ID' of its parent.
Somehow I can figure out how to join data from other tables but I cant figure this out...
-- Update: I forgot to show an example of the output I'm looking for, in a perfect world I would get the following..
ID | Group | Status | Name
3 | Group 2 | 400 | WINXP32
4 | Group 1 | 400 | WIN7
5 | Group 1 | 400 | WIN2K8
I would (i think) filter out the groups from the output by doing a where status > 0
Thanks everyone for the quick feedback !
Try like thsi
SELECT ID,
CASE WHEN STATUS = 0 THEN (SELECT Root WHERE Parent = ID)
END [Group]
Status,
Name
FROM TABLE1
WHERE STATUS <> 0
Do you mean something like this (Self join in SQL standard)?
If it's possible that you have records with missing Parent ID:
select t1.name,
t2.name as "Group"
from tab t1
left join tab t2
on t1.parent = t2.id
where t1.status > 0;
If Parent ID is always present, you can use an inner join:
select t1.name,
t2.name as "Group"
from tab t1, tab t2
where t1.parent = t2.id
and t1.status > 0;
Otherwise, please can you explain what you need?
I think your main problem is to use the same table twice. This is achieved using different aliases like Corrado Piola explained it.
select t1.name, t2.name from mytab t1, mytab t2 where ...
Now t1 and t2 are acting like different tables.
Select
m.id,g.Name,m.Status,m.Name
from
table1 M,
table2 G
where
m.Status >0
and g.Status = 0
and m.Parent = g.id

How I can remove rows from two tables with join in SQL Server?

Table1.
id | name
1 | Test
Table2.
id | post | table1_id
1 | mypst| 1
I need to remove a row from Table1 where id=1 and all rows from Table2 where table1_id=(1 is id from Table1).
I'm trying this:
DELETE FROM Table1
INNER JOIN Table2 ON Table2.table1_id = Table1.id AND Table1.id = 1
but I'm getting error:
Incorrect syntax near the keyword 'INNER'.
What's wrong?
You shouldn't be doing deletes from multiple tables in one query
DELETE FROM Table2 WHERE table1_id = 1;
DELETE FROM Table1 WHERE id = 1
should be fine. Is there any specific reason you wish to do it using JOIN?
Lets assume you are doing things right and made a foreign key (Table2.table1_id = Table1.id). Then all you need is to set ON DELETE CASCADE on Table1.
In this case everything you should do is:
DELETE FROM Table1 WHERE id = 1
...and relax. This is data consistency, dude :)

How do I update tables in SQL so that related strings match?

Suppose I have 2 tables
Table1
ID Path
-- ----
1 PathA
2 PathB
3 PathC
4 PathD
Table2
ID Path Table1ID
-- ---- --------
23 PathA 1
24 PathX 2
25 PathC 3
26 PathZ 4
In the above, PathX should be PathB and PathZ should be PathD
How do I sync all the path values in Table2 with values in Table 1, the tables could be large so would like to check for all values that do not match and update them.
Cheers
Using MS SQL Server 2005
The following is I believe the simplest:
UPDATE TableB SET Path = TableA.Path
FROM TableA
WHERE TableB.Id = TableA.ID AND TableB.Path <> TableA.Path
I suppose this should do the trick...
UPDATE Table2 SET
Path = t1.Path
FROM Table2 t2
INNER JOIN Table1 t1 ON
t1.ID = t2.Table2ID
WHERE
t1.Path != t2.Path;
Edit: Sorry I believe I misinterpreted your request. I thought you wanted Table2 values into Table1. I've changed it to be the other way around.
If i am understanding your question correctly this will update the paths on table2 with values from table1
Update Table2
set path = b.path
From Table2 a
Left outer join Table1 b
on a.Table1ID = b.ID
Where ltrim(rtrim(a.Path)) <> ltrim(rtrim(b.Path))
Your example demonstrates how you can (will) get anomalies if you do not normalize your tables.
In Table2 either store Table1ID or Path but not both, you can query for the other (perhaps recreate your current Table2 as a VIEW. Whichever column you choose for Table2, ensure you have a foreign key on it referencing Table1.
The best way
UPDATE TableB SET Path = TableA.Path
FROM TableA
WHERE TableB.Id = TableA.ID AND TableB.Path <> TableA.Path