Database Query Help required in MySQL - sql

I am looking for help in writing a query of retrieving the values from 2 tables in MySQL.
The scenario is
Table A
ID Name Marks
===================
23 John 67
45 Mark 45
12 Ram 87
Table B has the following Structure
ID Name Evaluation Marks
==============================
45 Mark 34
78 Chris 09
98 Nancy 10
23 John 12
I am trying to write a query, where if I execute the following query
Select "SOMETHING" from Table A where Id=45
I should get Marks Column as 45+34=79, which should fetch and sum from the both the Tables A and Table B.
If I execute the query with the Id=12.
Since the Id=12, does not exists in the Table B, I should get the Marks as 87.
What would a query for the above?

I assume that the id occurs only once in your tables table a, but could be missing in both. If it always exists in table a, you can use a LEFT JOIN instead of the UNION.
SELECT COALESCE(SUM(marks), 0)
FROM
(
SELECT marks FROM a WHERE id = 45
UNION ALL
SELECT SUM(evaluation_marks) AS marks FROM b WHERE id = 45
) x
Edit
If you have all users in table a, then use
SELECT a.marks + COALESCE( SUM( b.evaluation_marks ), 0 )
FROM a
LEFT OUTER JOIN b ON ( b.id = a.id )
WHERE a.id = 45
GROUP BY a.id, a.marks
You should consider changing your table model though. Why do you store name and id twice? Can't you do it like that:
id name marks evaluation marks
=======================================
12 Ram 87 0
23 John 67 12
45 Mark 45 34
78 Chris 0 9
98 Nancy 0 10

Related

Getting multiple columns from TWO tables using a WHERE EXISTS statement

I'm trying to use two name column's in tables and find the similarities/differences using SQL Server. I would like to print a list of students Table 1 that are not present in Table 2, along with all their respective scores and grade. However I am having trouble populating multiple columns with my current script. My script does not populate the test scores but instead prints only NULL values. I've included the table format's and where I am with my both script's so far. Right now, all the score fields are printing NULL values even when they have populated fields in Table2.
TABLE_1_Today's_List
Name1
Kevin
James
Roger
Bob
TABLE_2_Combined_Scores
Name2
Grade
Score_1
Score_2
Score_3
Score_4
Kevin
10
25
34
12
45
Bob
9
25
23
65
87
Roger
10
43
54
25
98
James
12
43
54
25
98
Students in Table 1 that are also in Table 2:
SELECT c.Name1, Score_1,Score_2,Score_3,Score_4
FROM TABLE_1_Today's_List c
WHERE EXISTS (SELECT c2.Name2,Score_1,Score_2,Score_3,Score_4
FROM TABLE_2_Combined_Scores c2
WHERE c2.Name2 = c.Name1
and Grade = '10');
^This script returns NULL values for all the Score fields but correctly maps the students in both tables. I would like to populate the the Score fields with the results from Table2
Students in Table 1 that are not in Table 2:
SELECT c.Name1, Score_1,Score_2,Score_3,Score_4
FROM TABLE_1_Today's_List c
WHERE NOT EXISTS (SELECT c2.Name2,Score_1,Score_2,Score_3,Score_4
FROM TABLE_2_Combined_Scores c2
WHERE c2.Name2 = c.Name1
and Grade = '10');
^This script returns NULL values for all the Score fields but correctly maps the students in table1 but not table2. I would like to populate the the Score fields with the results from Table2
Ideal Output:
Name1
Score_1
Score_2
Score_3
Score_4
Kevin
25
34
12
45
Roger
43
54
25
98

Linking different ids through interactor

I want to link different ids through the common interactor. It is bit complex but i will try my best to frame the problem.
Here are the list of steps
1. Extract id from table A.
Table A
ID Interactor
1 30
2 40
Get the list of interactors corresponding to id from table B. for example,
select * from table B where id = 1
Table B
ID Interactors
1 30
1 32
1 33
1 36
1 38
1 39
Iterate through each interactor from the list and get the list of ids from table A.
Table A
ID Interactors
1 30
70 32
76 33
Null 36
89 38
75 39
2 45
2 40
2 43
4.Join these different ids so that when i select 1 i should get the below result.
Select * where id = 1
Result
ID Interactors
1 30
70 32
76 33
89 38
75 39
I want to achieve this using sql.
Try this:
select B.ID, B.Interactors
from A inner join B
where A.Interactors = B.Interactors
and A.ID = 1
From step 3 you have table A, and before that you have table B.
You can use simple inner join with some where condition to get your desired result.
Select Id, Interactors from
( select tableA.id, tableA.Interactors
from tableA
inner join tableB
on tableA.Interactors = tableB.Interactors
and tableA.Id is not null --- this is required since in your output record having NULL id correspond to tableA is not considered
) as db
where db.Id = 1 ---- you can apply any filter over there to get your desired result.

Re-Organize Access Table by converting Rows to Columns

I'm pretty new to access and SQL and need some help re-organizing a table. I have the following table (sorry for the table below - having trouble posting):
ID GroupID Distance Code Start_Finish
1 44 7 A S1
2 44 14 A F1
3 45 12 B S1
4 45 16 B F1
5 45 31 C S2
6 45 36 C F2
7 45 81 B S3
8 45 88 B F3
And need for the table to be transformed into:
GroupID Code Start_Distance Finish_Distance
44 A 7 14
45 B 12 16
45 C 31 36
45 B 81 88
try something like this
Select GroupID, Code, min(distance) as Start_distance, max(distance) as Finish_distance
from Table
group by GroupID, Code
If the min and max functions don't give you what you need, try it with First() and Last() instead.
Oops - just noticed you have 2 different entries in the output for GroupID 45 Code B - is that a requirement? With that data structure and requirement, the problem gets much more difficult.
Now I see the final column in the 1st table - I think that can be used to get the output you want:
Select GroupID, Code, mid(start_finish,2) as T, min(distance) as Start_distance, max(distance) as Finish_distance
from Table
group by GroupID, Code, T
You can use conditional aggregation for this.
select GroupID
, CODE
, max(case when Left(Start_Finish, 1) = 'S' then Distance end) as Start_Distance
, max(case when Left(Start_Finish, 1) = 'F' then Distance end) as Finish_Distance
from SomeTable
group by GroupID
, CODE

Assigning a value of data for each record having the same condition in SQL Server 2008

I have a table in SQL Server 2008 like:
Period Name Value
1 A 10
2 A 20
3 A 30
4 A 40
1 B 50
2 B 80
3 B 70
4 B 60
What I need to write a select query includes a new column MainValue which contains the value where period=4 for a name for each data.
Example:
Period Name Value MainValue
1 A 10 40
2 A 20 40
3 A 30 40
4 A 40 40
1 B 50 60
2 B 80 60
3 B 70 60
4 B 60 60
How can I provide this? I tried the one below, but it is not working as I want.
Select
*,
(select Value where Period = 4) as MainValue
from myTable;
Any help would be appreciated.
Try this:
SELECT Period, Name, Value,
MAX(CASE WHEN Period=4 THEN Value END) OVER (PARTITION BY Name) AS MainValue
FROM mytable
The query uses a window function with a condition applied over Name partitions: the function returns the Value corresponding to Period=4 inside each partition.
You can do this a number of ways. A correlated sub-query as the column, a cross apply to a correlated query, or a cte. I personally like the cte approach. It would look something like this.
with MainValues as
(
select Name
, Value
from SomeTable
where Period = 4
)
select st.*
, mv.Value as MainValue
from SomeTable st
join MainValues mv on st.Name = mv.Name

sqlquery insert data from one table to other with id from columnname

I have an old database with some complex joining of the data. As given below
Subjects
Id Name
-------------------------------
1 Math
2 Science
3 English
Results
Id StudentId Math MathMax Science ScienceMax English EnglishMax TotalMarks Max
-----------------------------------------------------------------------------------------
1 81 5 10 6 10 3 10 14 30
2 82 8 10 8 10 9 10 25 30
3 83 7 10 8 10 7 10 22 30
Now I am trying to convert it to more easy and readable database. So I come up with the tables like
Results
ResultId StudentId TotalMarks MaxMarks
-------------------------------------------
1 81 14 30
2 82 25 30
3 83 22 30
ResultDetails
Id ResultId SubjectId Marks MaxMarks
--------------------------------------------------------
1 1 1 5 10
2 1 2 6 10
3 1 3 7 10
& so one
Now the real question I can insert data in the new Results table but I am confused on the second table. I can't understand that how to pass column name of one table and get the id of that name from second table and insert it in the third one.
I am trying on but can't understand the right commands to achieve this. My database already have 50000+ records and I have to merge them according to this new tables.
Assuming this is a one-off conversion of data, and you've already populated your new Results table, something as simple as the following should work:
INSERT INTO ResultDetails(ResultId, SubjectId, Marks, MaxMarks)
SELECT
R.StudentId,
1 AS SubjectId,
OldR.Math AS Marks,
OldR.MathMax AS MaxMarks
FROM Results R
INNER JOIN OldResults OldR ON R.StudentId = OldR.StudentId
INSERT INTO ResultDetails(ResultId, SubjectId, Marks, MaxMarks)
SELECT
R.StudentId,
2 AS SubjectId,
OldR.Science AS Marks,
OldR.ScienceMax AS MaxMarks
FROM Results R
INNER JOIN OldResults OldR ON R.StudentId = OldR.StudentId
INSERT INTO ResultDetails(ResultId, SubjectId, Marks, MaxMarks)
SELECT
R.StudentId,
3 AS SubjectId,
OldR.English AS Marks,
OldR.EnglishMax AS MaxMarks
FROM Results R
INNER JOIN OldResults OldR ON R.StudentId = OldR.StudentId
It's not a very elegant solution, but it doesn't need to be for a one-off conversion.