t-sql merging two tables and replace null values - sql

I have these two tables, and that what I want is to compare them to know if there is any null value in table 2, if there is, replace the existing value in table 1 by the null value in table 2 (by the code column that is the primary key).
Table 1
Code Name Points
1 Juan Perez 10
2 Marco Salgado 5
3 Carlos Soto 9
4 Alberto Ruiz 12
5 Alejandro Castro 5
10 Jonatan Polanco 0
11 JD NULL
Table 2
Code Name Points
1 Juan Perez 10
2 Marco Salgado 5
3 Carlos Soto 9
4 Alberto Ruiz 12
5 Alejandro Castro 5
10 Null 0
11 JD 9
The resulting table should look like this
Table 2
Code Name Points
1 Juan Perez 10
2 Marco Salgado 5
3 Carlos Soto 9
4 Alberto Ruiz 12
5 Alejandro Castro 5
10 Jonatan Polanco 0
11 JD 9

If you are trying to update the rows that have null values in Points column, You just need to join the two tables and add a where clause to limit the rows to the ones you want to update. Something like this
UPDATE t2
SET Points = t.Points
FROM table_1 t
JOIN table_2 t2
ON t.code = t2.code
WHERE t2.Points IS NULL

Related

Cant merge two queries with different columns

I'm studying SQL and somehow I'm stuck with a question. I have 2 tables ('users' and 'follows').
Follows Table
user_id
follows
date
1
2
1993-09-01
2
1
1989-01-01
3
1
1993-07-01
2
3
1994-10-10
3
2
1995-03-01
4
2
1988-08-08
4
1
1988-08-08
1
4
1994-04-02
1
5
2000-01-01
5
1
2000-01-02
5
6
1986-01-10
7
1
1990-02-02
1
7
1996-10-01
1
8
1993-09-03
8
1
1995-09-01
8
9
1995-09-01
9
8
1996-01-10
7
8
1993-09-01
3
9
1996-05-30
4
9
1996-05-30
Users Table
user_id
first_name
last_name
school
1
Harry
Potter
Gryffindor
2
Ron
Wesley
Gryffindor
3
Hermonie
Granger
Gryffindor
4
Ginny
Weasley
Gryffindor
5
Draco
Malfoy
Slytherin
6
Tom
Riddle
Slytherin
7
Luna
Lovegood
Ravenclaw
8
Cho
Chang
Ravenclaw
9
Cedric
Diggory
Hufflepuff
I need to list all rows from follows where someone from one house follows someone from a different house. I tried to make 2 queries, one to get all houses related to follows.user_id and another one with all houses related to follows.follows and "merge" then:
select a.nome_id, a.user_id_house, b.follows_id, b.follows_house
from ( select follows.user_id as nome_id
, users.house as user_id_house
from follows inner join users
ON users.user_id = follows.user_id
) as a,
( select follows.follows as follows_id
, users.house as follows_house
from follows inner join users
ON follows.user_id = users.user_id
) as b
where a.user_id_house <> b.follows_house;
The problem is that the result is like 400 rows, its not right. I have no idea how I could solve this.
Try this
SELECT follows.user_id, users.school, followers.user_id, followers.school FROM follows
JOIN users ON follows.user_id=users.user_id
JOIN users as followers ON follows.follows=followers.user_id
WHERE users.school <> followers.school
Note: Pay attention to naming in my answer
Thanks for correcting to Thorsten Kettner

Simply stack column to existing table

Simple question. Say I have a table with two columns, PersonID and CardID and 10 rows. I have another Table that contains 1 column, Code and 10 rows. I simply want to stack the codes to the other table. Note that is does not matter which person gets which code, they should all just get one.
At the moment I find myself adding rownumbers in both tables and updating were TableA.ID = TableB.ID. But this seems overly complex for such a simple taks.
Any suggestions?
TableA
PersonID CardID
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
Table B
Code
Random1
Random2
Random3
Random4
Random5
Random6
Random7
Random8
Random9
Random10
Desired Result:
PersonID CardID Code
1 1 Random1
2 2 Random2
3 3 Random3
4 4 Random4
5 5 Random5
6 6 Random6
7 7 Random7
8 8 Random8
9 9 Random9
10 10 Random10
Again, code order does not matter. Each person, one code. That's it.
You need not to append 1 extra column to each row, You can use CTE with RowNum like :
;WITH CTE_Results
AS (
SELECT ROW_NUMBER() OVER (ORDER BY Code) as ID, Code
from TableB B
)
select A.PersonId, A.CardID, CTE_Results.Code from CTE_Results
INNER JOIN TableA A ON A.PersonId= CTE_Results.ID
Working SQL Fiddle is : http://sqlfiddle.com/#!18/f8f86/9
Result will be like :
PersonId CardID Code
1 1 Random1
2 2 Random10
3 3 Random2
4 4 Random3
5 5 Random4
6 6 Random5
7 7 Random6
8 8 Random7
9 9 Random8
10 10 Random9

How to implement Relay Teams in a Track & Field Database

I have a track and Field Database with these tables (simplified):
Performance Table
Row Athlete Event Mark Meet
1 1 3 0:55 A
2 2 2 2:25 A
3 3 3 0:54 A
4 4 4 4:10 A
5 2 2 2:11 A
6 3 2 2:12 B
7 1 1 10 C
Athlete Table
Row Name Age Sex
1 Joe 13 M
2 Amy 15 F
3 John 16 M
4 Tim 17 M
So I understand how to implement this for an event with only 1 athlete (e.g. 100 m dash), but how would I include a relay event with 4 athletes. So, for example a 4x400 relay would need 4 athletes. In other words, some events have only 1 athlete and some have more than one. I am not sure if I should use:
Linking Table
Add 4 Columns
Do a table like below.
Other
Option 3 Table
Performance Table (Event 5 is a relay)
Row Athlete Event Mark Meet
1 1 3 0:55 A
2 2 2 2:25 A
3 3 3 0:54 A
4 4 4 4:10 A
5 2 2 2:11 A
6 3 2 2:12 B
7 1 5 9:34 C
8 2 5 9:34 C
9 3 5 9:34 C
10 4 5 9:34 C
Are you going to have events in the system before they are finished? For example, today's meet will include a 4x400 and here are the runners...
If that's the case then you'll need the linking table that you referred to because you want to be able to have that data stand on its own. It would just have the event_id and athlete_id in it so that you could have that set up. That would also be the PK (Primary Key) for the table and you would then use those two columns as the FK (Foreign Key) to the Performance table that you have at the end. If the data will never exist without times then you could just skip the link table and have the Performance table, although having the link table still wouldn't hurt in that case.

Archive old Information in table

I want to archive old information in my table.
If the value in T1C2 is a number (or less than 5 characters) then I want to replace it with the word archive and the value in T1C1.
T1C1 T1C2
1 London
2 New York
3 2342
4 Cardiff
5 2394
6 Sydney
7 2342
8 2343
9 7345
Result
T1C1 T1C2
1 London
2 New York
3 Archive3
4 Cardiff
5 Archive5
6 Sydney
7 Archive7
8 Archive8
9 Archive9
You can do this with an update:
update mytable
set t1c2 = 'Archive' + cast(t1c1 as varchar(255))
where t1c2 not like '%[^0-9]%';
You could also use isnumeric() for the where, but I you need to check for other conditions:
where isnumeric(t1c2) = 1 and t1c2 not like '%[.e]%'
Try this one :
UPDATE yourtable
SET T1C2 = 'Archive' + Cast(T1C1 AS VARCHAR(100))
WHERE isnumeric(T1C2) = 1
OR Len(T1C2) < 5

SQL: Create view from 2 tables printing null values when no records

I have in my DB these 2 tables:
LESSONS RATINGS
ID | NAME ID | LESSON | RATING
1 lesson1 1 1 4
2 lesson2 2 2 2
3 lesson3 3 1 5
4 lesson4 4 4 2
5 lesson5 5 3 1
6 lesson6 6 2 5
7 lesson7 7 6 3
And I want a View that show me something like this:
LESSONS_RATINGS
IDL| NAME | RATING
1 lesson1 4.5
2 lesson2 3.5
3 lesson3 1
4 lesson4 2
5 lesson5 NULL
6 lesson6 3
7 lesson7 NULL
But what I've been able to get so far is this:
LESSONS_RATINGS
IDL| NAME | RATING
1 lesson1 4.5
2 lesson2 3.5
3 lesson3 1
4 lesson4 2
6 lesson6 3
Notice that NULL records are missing. That's why in table RATINGS there are no records of lessons 5 and 7. I'm doing this:
CREATE OR REPLACE VIEW `LESSONS_RATINGS` AS
select
`l`.`ID` AS `IDL`,
`l`.`NAME` AS `NAME`,
CASE WHEN AVG(`lr`.`RATING`) IS NULL THEN NULL ELSE AVG(`lr`.`RATING`) END AS `RATING`
from
`LESSONS` AS `l`,
`RATINGS` AS `lr`
where
(`l`.`ID` = `lr`.`ID`)
group by `l`.`ID`;
Use an OUTER JOIN:
select
`l`.`ID` AS `IDL`,
`l`.`NAME` AS `NAME`,
AVG(`lr`.`RATING`) AS `RATING`
from
`LESSONS` AS `l` LEFT JOIN `RATINGS` AS `lr`
ON `l`.`ID` = `lr`.`ID`
group by `l`.`ID`;
Also, I don't think there is a need for the Case statement -- you can just use AVG(lr.rating).
A Visual Explanation of SQL Joins