MySQL and gathering and counting information from multiple tables - mysql

I am having issues figuring out how to do this. This isnt the real problem, but something very similar.
I have table A
ID Name
10 Bob
11 Tom
12 Suzie
13 Billy
14 Rob
15 Ben
Then table B, where B_ID references to ID in table A
B_ID Value
11 1500
13 2600
Then Table C where C_ID references to ID in table A
C_ID MatchedWith
10 11
12 13
14 11
15 11
The intention of this query is to list the Names of the people in table B, and how many people that are matched with them from C
...So the resulting query would give something like:
Name Count
Tom 3
Bily 1
I am completely boggled on how to do this, so any help would be super! thank you!

SELECT
A.Name,
COUNT(*) as 'Count'
FROM
C
JOIN B
ON C.MatchedWith = B.B_ID
JOIN A
ON A.ID = B.B_ID
GROUP BY A.Name
ORDER BY Count DESC;

Related

UNION ALL not working with different columns

Left join rows and right table rows in same column
I have two tables (Manager and Worker). The name of workers under a manager should come below manager name. The expected output is presented below:-
Manager Table:
ManagerCode Name Age Location
1 Chris 52 A
2 Rick 55 B
3 David 50 C
Worker Table
ManagerCode WName Age
1 Harry 33
1 Phil 40
2 Johnny 28
2 Jeff 47
Expected table:
ManagerCode Name Location
1 Chris A
1 Harry A
1 Phil A
2 Rick B
2 Johnny B
2 Jeff B
3 David C
Union All is creating problem for Location column as number of columns become different. I could use null as Location for worker table. But there are several columns like location in Manager. Is union correct option ?
You need to join the Worker and Manager tables to get the location codes for the workers from their corresponding managers. Then you can union that with the manager table.
SELECT ManagerCode, Name, Location
FROM (
SELECT ManagerCode, Name, Location, 1 AS isManager
FROM Manager
UNION ALL
SELECT w.ManagerCode, w.Name, m.Locationm, 0 AS isManager
FROM Worker AS w
JOIN Manager AS m ON w.ManagerCode = m.ManagerCode
) AS x
ORDER BY ManagerCode, isManager DESC
The isManager column is used to order the workers after their managers.

Remove duplicates in Join statement in mysql and group

I have two tables
table1
Name marks
John 50
Smith 70
Adam 60
Roy 70
table2
Score Grade other
50 C 1.5
60 B 0.7
70 A 0.8
70 A 1.0
I want to get how many people have got A, B, C passes
I want to get an output as
Grade Count
C 1
B 1
A 2
Query I tried was
SELECT table2.Grade,
COUNT(DISTINCT table2.Grade) as count
FROM table1
LEFT JOIN table2
ON table1.Mark = table2.Score
GROUP BY table2.Grade;
But it Gives
Grade Count
C 1
B 1
A 4
So How to remove the duplicates ?
Please help.
At your second table, you got duplicate rows:
Score Grade other
50 C 1.5
60 B 0.7
70 A 0.8
70 A 1.0
Here, there are to A's, and when you joing with first table according to the field "Grade--Score", the whole join is:
Jhon 50 C
Smith 70 A
Smith 70 A --> Second A from second table
Adam 60 B
Roy 70 A
Roy 70 A --> Second A from second table
So group by and count will result 4 for the field grade here:
A 4 --> 2 Smith and 2 Roy
B 1
C 1
So, to get how many single person per grade:
select tb2.Grade GradeMark, count(*) TotalPersons
from table1 as tb1
left join (select tbi2.Score, distinct(tbi2.Grade), tbi2.other, from table2 tbi2) as tb2 on tb2.Grade = tb1.marks
group by tb2.Grade
This query will select distinct values from table2, join with table one and count the results per grade so you should get:
A 2
B 1
C 1
You don't need a JOIN for this. You can try like below using a simple group by and get the count()
select Grade, count(*) as `Count`
from table2
group by Grade;

Getting the records on right table

I am facing some tables join issue in MySQL. Can anyone help me. I have two tables in mysql database. I want to join both tables and get the records. Here is the structure of the both table.
exam_attend
===========
id
student_id
Answer
======
id
student_id
exam_attend
===========
id student_id
-- ----------
1 10
2 11
3 12
Answer
======
id student_id
-- ----------
1 10
2 10
3 13
4 12
5 14
I want list of the user who giving the answer without attending exam. Please help me.
Desired result
id student_id
-- ----------
3 13
5 14
Use:
SELECT A.id, A.student_id FROM Answer A
LEFT OUTER JOIN exam_attend E ON E.student_id=A.student_id
WHERE E.student_id IS NULL
Below SQL useful to you.
select id, student_id from Answer
where student_id not in (select distinct student_id from exam_attend)

SQL Query to match unlinked data

Say I have three tables:
TABLE A
idA variable
1 Number of hats
2 Number of scarves
3 Number of mittens
TABLE B
idB name
1 Andy
2 Betty
3 Cedric
4 Daphne
TABLE C
idA idB value
1 1 15
1 2 2
1 3 89
2 1 10
2 3 3
2 4 1504
3 2 12
3 3 4
3 4 1
Looking at the table, it's relatively simple to work out - we know how many hats (2) and mittens (12) that she owns, but not how many scarves. Likewise, for Daphne we know how many scarves (1504) and mittens (1) she owns, but not the amount of hats.
However, I'd like a list of fields that there ISN'T information for - I would have a returned result looking something like this (if I asked for Andy)
idA variable
3 Number of mittens
Any idea how I do that? :)
The following query works:
SELECT B.name, A.variable
FROM B
CROSS JOIN A
LEFT JOIN C ON C.idA = A.idA AND C.idB = B.idB
WHERE C.value IS NULL
Its the CROSS JOIN that is key, it says JOIN every record in B to every record in A. Once you've done that you can easily check which combinations of idA and idB don't have a corresponding record in C.
Tested on SQLFiddle
Result:
NAME UNKNOWN VARIABLE
-------------------------------
Andy Number of mittens
Betty Number of scarves
Daphne Number of hats
You can use joins to associate 2 tables.
In your case, if you ask for Andy and you wanna know the number of mittens, you'll have:
SELECT name, value
FROM B
INNER JOIN C on B.idB = C.idB
WHERE id.A = 3
Responding to your comment, you try something like that:
SELECT name, variable
FROM B
RIGHT JOIN C on B.idB = C.idB
RIGHT JOIN A on C.idA = A.idA
WHERE C.idA IS NULL
select idA, variable
from a
where idA not in (select idA from c where idB = 1)

How to fetch the most recent timestamped record for the same id from MySQL table? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Fetch the row which has the Max value for a column
I have an audit table of people and the number of shares they own at a particular timestamp. How do I fetch the most recent record for a given id?
mysql audit table
id name shares dateadded
1 Abc 12 2012-10-06 12:18:21
2 Klm 23 2012-10-06 12:18:21
3 Jim 45 2012-10-06 12:18:21
1 Abc 35 2012-11-06 12:18:21
1 Abc 65 2012-11-17 12:18:21
2 Klm 13 2012-11-06 12:18:21
My desired output :
id name shares dateadded
1 Abc 65 2012-11-17 12:18:21
2 Klm 13 2012-11-06 12:18:21
3 Jim 45 2012-10-06 12:18:21
I could do something like this :
select a.* from audittable a join audittable b
on a.id = b.id
where a.dateadded > b.dateadded;
But that gives me only those most recent records that are repeating. In this case ids 1,2 and not 3. How to get a list of most recent records for all IDs without sub-queries or temp tables?
You will need a subquery, however not subselects (which have a very negative performance hit).
JOIN against a subquery which returns the id and MAX(dateadded) aggregate. The subquery join is needed to be able to match all the other column values in the row containing the latest timestamp.
SELECT
audittable.id,
name,
shares,
audittable.dateadded
FROM
audittable
/* Subquery returns id dateadded grouped by id */
JOIN (
SELECT id, MAX(dateadded) AS dateadded FROM audittable GROUP BY id
/* JOIN condition is on both id and dateadded between the two tables */
) maxtimestamp ON audittable.id = maxtimestamp.id AND audittable.dateadded = maxtimestamp.dateadded
Here is a demonstration on SQLfiddle
Without subqueries, you are limited to this
SELECT id, MAX(dateAdded)
FROM audittable
GROUP BY id
If you want the other columns, you need a subquery like Michael Berkowski's answer