I have 2 tables student and attendance. I need to join both tables and get the result like number of total absents and number of student in particular class and classname. I need a single query to get the below results
tbl_student:
admission_no(PK) student_name student_class
345 John X A
352 Sachin X A
322 Steve IX A
123 Pinky X A
343 Rose IX A
tbl_admission:
admission_no(FK) date_absent
354 2015-03-30
123 2015-03-30
322 2015-03-30
Result should be like this:
Date_absent total_absent total_students student_class
2015-03-30 2 3 X A
2015-03-30 1 2 IX A
you can do something like this to manage it in single query:
SELECT date_absent, total_absent, total_students, a1.student_class
FROM (
SELECT date_absent, count( tbl_admission.admission_no ) AS total_absent, tbl_student.student_class
FROM `tbl_admission`
JOIN `tbl_student` ON tbl_student.admission_no = tbl_admission.admission_no
GROUP BY tbl_student.student_class
)a1
JOIN (
SELECT count( tbl_student.admission_no ) AS total_students, tbl_student.student_class
FROM tbl_student
GROUP BY tbl_student.student_class
)a2
ON a1.student_class = a2.student_class
ORDER BY `a1`.`student_class` DESC
Related
This is my sql query to get the following table below :
select c.name, s.company, p.qty, p.qty * p.price as Total
from client c, purchase p, stock s
where c.clno = p.clno AND s.company = p.company
group by c.name, s.company, p.qty, p.qty * p.price
order by sum(p.qty) desc
The output of the above query looks like this :
Name | Company | Qty | Total
John ABC 12 100
Bob XYZ 10 150
John ABC 5 50
Bob XYZ 20 250
Bob XYZ 2 20
Nav QRS 10 150
John ABC 10 150
I want to have the query to get the output as the following :
Name | Company | Qty | Total
John ABC 27 300
Bob XYZ 32 420
Nav QRS 10 150
As of now your query uses GROUP BY but does not actually aggregates data. You want to GROUP BY name and company, and SUM the quantities and amounts, like :
select c.name, s.company, SUM(p.qty), SUM(p.qty * p.price) as Total
from client c
inner join purchase p on c.clno = p.clno
inner join stock s on s.company = p.company
group by c.name, s.company
order by Total desc
Other remarks regarding your query :
always use explicit joins instead of implicit ones
you can use column aliases in the ORDER BY clause (here, Total ; this can make the query easier to read
I have a table that looks like this:
id name yearofstudy mark
1 Alain A 2 75
2 Michael B 3 85
3 Chen C 1 55
4 Caroline D 2 60
5 Mohamed E 2 60
6 Alex F 1 55
7 Sofia O 3 78
8 Samir O 1 85
9 Rob G 2 78
10 Big K 3 55
And I'm trying to get the id, name, year and mark of the students with the lowest (and highest) mark in each year which would give:
id name yearofstudy mark
3 Chen C 1 55
4 Caroline D 2 60
10 Big K 3 55
SQL isn't my strong point and I've been trying using the MIN() function but I haven't managed to get it right yet and would really appreciate some help.
Using a subquery to get the min() and max() for each yearofstudy, and joining it to the original table. (You did say you wanted lowest and highest, right?)
select t.id, t.name, t.yearofstudy, t.mark
from t
inner join (
select
yearofstudy
, min(mark) as minMark
, max(mar) as maxMark
from t
group by yearofstudy
) as m
on t.yearofstudy = m.yearofstudy
and (t.mark = minMark or t.mark = maxMark)
or for just the lowest mark per year:
select t.id, t.name, t.yearofstudy, t.mark
from t
inner join (
select
yearofstudy
, min(mark) as minMark
from t
group by yearofstudy
) as m
on t.yearofstudy = m.yearofstudy
and t.mark = minMark
You could write the query as follows:
SELECT t1.* from your_table t1
INNER JOIN (
SELECT yearofstudy, MIN(marks) as marks
FROM your_table GROUP BY yearofstudy
) t2
ON t1.yearofstudy = t2.yearofstudy
AND t1.marks = t2.marks
GROUP BY t1.yearofstudy
ORDER BY t1.yearofstudy, t1.id;
If all the MIN records for the yearofstudy are required, then you could simply remove GROUP BY t1.yearofstudy
Demo
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;
What I want to do is sum each metric of each transaction in the "TRANSACTION" table with a common customer_id in a single query. The output should look like the "OUTPUT" table.
I can see how to select the columns of interest through a JOIN of TRANSACTIONS and CUSTOMER on 'customer_id', but what I don't know is how to sum the metrics at the same time.
TRANSACTIONS
transaction customer_id metric_1 metric_2
1 1 0 564
2 1 0 762
3 1 5.305 8367
4 2 0 150
5 2 3.125 4109
6 2 6.18 1853
7 3 0 61
8 3 0 1
9 3 0 4
CUSTOMER
customer_id customer_name
1 XXX
2 YYY
3 ZZZ
DESIRED
customer_name metric_1 metric_2
XXX 5.305 9693
YYY 9.305 6112
ZZZ 0 66
You could use SUM and group by customer_id and customer_name.
SELECT
c.customer_name,
metric_1 = SUM(t.metric_1),
metric_2 = SUM(t.metric_2)
FROM Transactions t
INNER JOIN Customer c
ON c.customer_id = t.customer_id
GROUP BY t.customer_id, c.customer_name
You can simply do that using an Implicit Join. See my answer below:
SELECT
customer_name,
SUM(metric_1) AS metric_1,
SUM(metric_2) AS metric_2
FROM Transactions,Customer
WHERE Transactions.customer_id=Customer.customer_id
GROUP BY customer_name
SEE DEMO HERE
I was successful in writing the query that lists salesmen that did sell to a particular customer, but not those that have not. I suspect it is because the same salesmen that sold to the specific customer, also sold to other customers.
select a.name from salesperson a inner join orders b on
a.salesperson_id = b.salesperson_id where cust_id="4";
I was thinking that modifying the same query like this would do the trick:
.... a.salesperson_id <> b.salesperson_id where cust_id="4";
But the result lists all the salesmen. This is most likely due to the fact that the same salesmen that were returned in the original query, also sold to other customers
The 3 tables look like this:
Salesperson table
salesperson_ID, Name, Age, Salary
1 Abe 61 140000
2 Bob 34 44000
5 Chris 34 40000
7 Dan 41 52000
8 Ken 57 115000
11 Joe 38 38000
Customer table
cust_ID, Name, City Industry Type
4 faralon sacramento H
6 Apple cupertino S
7 Honda NY B
9 Kolb Oshkosh B
Orders table
Number, Order_date, cust_id, salesperson_id, Amount
10 8/2/1996 4 2 540
20 1/30/1999 4 8 1800
30 7/14/1995 9 1 460
40 1/29/1998 7 2 2400
50 2/3/1998 6 7 600
60 3/2/1998 6 7 720
70 5/6/1998 9 7 150
Any help would be greatly appreciated. ~Alpinehyker
You can do something like this:
select a.name from salesperson a
left join orders b on a.salesperson_id = b.salesperson_id and b.cust_id="4"
where b.Number is null
So, get all salepersons, left join to orders for customer 4, and return only rows where there is no such order.
I am assuming that Number is the primary key for Orders, or at least not null.
All salespeople who have NOT sold to customer_ID 4:
SELECT s.Name FROM Salesperson AS s
LEFT JOIN Orders AS o
ON s.salesperson_ID = o.salesperson_ID
WHERE o.customer_ID <> 4
GROUP BY o.salesperson_ID;
Perhaps this will work
SELECT
s.*
FROM `Salesperson` AS s
LEFT JOIN `Orders` AS o ON o.`salesperson_id` = s.`salesperson_ID`
WHERE
o.`cust_id` NOT IN (4)
GROUP BY s.`salesperson_ID`;
Answer to your 2nd question:
SELECT
COUNT(*) AS num_of_orders
,s.`Name`
FROM `Salesperson` AS s
LEFT JOIN `Orders` AS o ON o.`salesperson_id` = s.`salesperson_ID`
GROUP BY s.`salesperson_ID`
HAVING num_of_orders >= 2;
...and 3rd question. (assuming you have your highAchiever table ready)
INSERT INTO `highAchiever`
(`Name`,`Age`)
SELECT
`Name`
,`Age`
FROM `Salesperson`
WHERE
`Salary` >= 100000;