Using one query's result into another - sql

I have this query which shows the below result, I want to use this MarksObtained and take out min, max and avg of each course and show it with the second query (have provided below).
select
CourseName, StdID, MarksObtained
from
stdmarks
inner join
course on course.courseid = stdmarks.examid
+--------------------------+-------+---------------+
| CourseName | StdID | MarksObtained |
+--------------------------+-------+---------------+
| Digital Logic | 1 | 20 |
| Visual Prog | 1 | 20 |
| Computer Arch and Design | 1 | 20 |
| Digital Logic | 2 | 20 |
| Visual Prog | 2 | 20 |
+--------------------------+-------+---------------+
This is the second query
select
distinct CourseName, TeacherName, SemName
from
teacher
inner join
stdcourseteacher on teacher.teacherid = stdcourseteacher.teacherid
inner join
course on course.courseid = stdcourseteacher.courseid
inner join
semester on stdcourseteacher.semid = semester.semid
+-------------------------+-------------+----------+
| CourseName | TeacherName | SemName |
+-------------------------+-------------+----------+
| Business Communications | Dr. Iman | Fall2021 |
| Calculus - 1 | Dr. Khalid | Fall2021 |
| Calculus - 2 | Dr. Khalid | Fall2020 |
+-------------------------+-------------+----------+
So it will basically show min, max and avg of each course achieved by the students.
What I want:
+-------------------------+-------------+----------+-----+-----+-----+
| CourseName | TeacherName | SemName | Min | Max | Avg |
+-------------------------+-------------+----------+-----+-----+-----+
| Business Communications | Dr. Iman | Fall2021 | 80 | 20 | 50 |
| Calculus - 1 | Dr. Khalid | Fall2021 | 70 | 15 | 45 |
| Calculus - 2 | Dr. Khalid | Fall2020 | 85 | 15 | 50 |
+-------------------------+-------------+----------+-----+-----+-----+
Sample data:
StdMarks table:
+-------+--------+---------------+
| StdID | ExamID | MarksObtained |
+-------+--------+---------------+
| 1 | 9 | 20 |
| 1 | 10 | 20 |
| 1 | 11 | 20 |
+-------+--------+---------------+
StdCourseTeacher Table:
+-------+----------+------------+-------+
| StdID | CourseID | TeacherID | SemID |
+-------+----------+------------+-------+
| 1 | 9 | 7 | 6 |
| 1 | 10 | 7 | 6 |
| 1 | 11 | 2 | 6 |
| 2 | 9 | 7 | 6 |
| 2 | 10 | 7 | 6 |
+-------+----------+------------+-------+
Exam Table:
+--------+--------+----------+----------+-------+----------+-----------+
| ExamID | EvalID | Topic | MaxMarks | SemID | CourseID | TeacherID |
+--------+--------+----------+----------+-------+----------+-----------+
| 1 | 3 | Mid-Term | 20 | 6 | 1 | 3 |
| 2 | 3 | Mid-Term | 20 | 6 | 2 | 4 |
| 3 | 3 | Mid-Term | 20 | 6 | 3 | 7 |
+--------+--------+----------+----------+-------+----------+-----------+
Course Table:
+----------+---------------------------+----------+
| CourseID | CourseName | Semester |
+----------+---------------------------+----------+
| 1 | Calculus - 1 | 1 |
| 2 | Business Communications | 1 |
| 3 | Introduction To Computing | 1 |
+----------+---------------------------+----------+
Semester Table:
+-------+------------+
| SemID | SemName |
+-------+------------+
| 1 | Spring2020 |
| 2 | Summer2020 |
+-------+------------+
Teacher Table:
+-----------+-------------+
| TeacherID | TeacherName |
+-----------+-------------+
| 2 | Dr. Ahmed |
| 3 | Dr. Khalid |
+-----------+-------------+

I think you want to use group by in order to use aggregate functions as follows:
select CourseName, TeacherName, SemName, min(MarksObtained), Max(MarksObtained), avg(MarksObtained)
from teacher T
inner join CT on CT.teacherid = T.teacherid
inner join course C on C.courseid = CT.courseid
inner join semester S on S.semid = CT.semid
inner join stdmarks M on M.examid = C.courseid
group by CourseName, TeacherName, SemName

Related

Get Field Hierachy

I have the following tables and I want to get the quantity of users by country:
+--------+------+:
| user | zone |
+--------+------+
| Paul | 7 |
+--------+------+
| John | 5 |
+--------+------+
| Peter | 6 |
+--------+------+
| Frank | 5 |
+--------+------+
| Silvia | 2 |
+--------+------+
| Carl | 4 |
+--------+------+
| Mark | 3 |
+--------+------+
Regions
+---------+-----------------+----------+--+
| zone_id | zone_name | idUpzone | |
+---------+-----------------+----------+--+
| 1 | Global | null | |
+---------+-----------------+----------+--+
| 2 | US | 1 | |
+---------+-----------------+----------+--+
| 3 | Florida | 2 | |
+---------+-----------------+----------+--+
| 4 | Orlando | 3 | |
+---------+-----------------+----------+--+
| 5 | China | 1 | |
+---------+-----------------+----------+--+
| 6 | Orlando Sector | 4 | |
+---------+-----------------+----------+--+
| 7 | Beijing | 5 | |
+---------+-----------------+----------+--+
so I get something like this
+---------+-----+
| Country | QTY |
+---------+-----+
| US | 4 |
+---------+-----+
| China | 3 |
+---------+-----+
Use a recursive CTE to get the highest level and then join:
with cte as (
select zone_id, zone_id as top_zone_id, zone_name as top_zone_name, 1 as lev
from regions
where parent_zone_id = 1
union all
select r.zone_id, cte.top_zone_id, top_zone_name, lev + 1
from cte join
regions r
on r.idUpzone = cte.zone_id
)
select cte.top_zone_name, count(*)
from users u join
cte
on u.zone = cte.zone_id
group by cte.top_zone_name;
Try this out:
SELECT
r.zone_name AS Contry, COUNT(*) QTY
FROM (
SELECT * FROM users u
INNER JOIN regions r ON u.zone = r.zone_id
) a
GROUP BY r.zone_name

How to update table 2 from the inserted data in table 1?

Can you help me on what query I to to update one table with data from another.
I have 2 tables for example:
tbl_med_take
| id | name | med | qty |
---------------------------------
| 1 | jayson | med2 | 3 |
| 2 | may | med2 | 4 |
| 3 | jenny. | med3 | 6 |
| 4 | joel. | med3 | 4 |
tbl_med
| id | med | stocks |
-----------------------------
| 1 | med1 | 20 |
| 2 | med2 |. 17 |
| 3 | med3 | 24 |
The output that I want in tbl_med:
tbl_med
| id | med | stocks |
-----------------------------
| 1 | med1 | 20 |
| 2 | med2 |. 10 |
| 3 | med3 | 14 |
First get the total consumed from med_tbl_take using
select med,sum(quantity) as total from tbl_med_take group by med
Then you can left join with your med_tbl and subtract.
select m.id,m.med,(m.stocks-ISNULL(n.total,0)) from tbl_med m
left join
(select med,sum(quantity) as total from tbl_med_take group by med) n
on m.med=n.med
CHECK DEMO HERE

Group selection by value of some fields

I have a following selection:
| EmployeeId | DepartmentName | Salary |
----------------------------------------
| 1 | A | 10 |
| 2 | A | 10 |
| 3 | A | 15 |
| 4 | A | 20 |
| 5 | A | 20 |
| 6 | B | 15 |
| 7 | B | 25 |
| 8 | B | 25 |
I want to group all rows by salary in each department and add this number of group to the selection.
Example of the result selection:
| EmployeeId | DepartmentName | Salary | Group |
------------------------------------------------
| 1 | A | 10 | 1 |
| 2 | A | 10 | 1 |
| 3 | A | 15 | 2 |
| 4 | A | 20 | 3 |
| 5 | A | 20 | 3 |
| 6 | B | 15 | 1 |
| 7 | B | 25 | 2 |
| 8 | B | 25 | 2 |
SELECT *
, DENSE_RANK() OVER (PARTITION BY DepartmentName
ORDER BY Salary) AS [Group]
FROM TableName

SQL Query in MANY- MANY RELATIONSHIP exactly one record with matching criteria

I have 3 like with many - many relationship
As:
TABLE 1 : select * from student;
| id | name |
| 1 | sone |
| 2 | stwo |
| 3 | sthree |
| 4 | sfour |
| 6 | ssix |
TABLE 2 : select * from course;
| id | name |
| 100 | CSE |
| 101 | ECE |
| 102 | ITI |
RELATION_SHIP TABLE : select * from student_course
| id | stu_id | cou_id |
| 1 | 1 | 101 |
| 2 | 2 | 102 |
| 3 | 2 | 100 |
| 4 | 3 | 100 |
| 5 | 3 | 101 |
| 6 | 1 | 101 |
| 1 | 6 | 101 |
I need to write a query to select a student with exactly one course 'CSE' and he should not have any other courses.
Thanks in advance
Use query:
SELECT
sc.`stu_id`,
COUNT(sc.`cou_id`) AS cnt
FROM
student_course sc
GROUP BY sc.`stu_id`
HAVING cnt = 1
AND GROUP_CONCAT(cou_id) LIKE
(SELECT
id
FROM
course
WHERE NAME = 'CSE')

List the name of division that all employees are working on some project(s)

List the name of division that ALL employees are working on some project(s). Namly, there not exists an employee who do is the full question. I'm having trouble getting an actual answer for this one, and my professor is being no help to telling me what I'm doing wrong. The code I have is
select dname
from division d, employee e, workon w
where e.did = d.did
and w.empid = e.empid
and not exists
(select empid
from workon
group by empid
having count (empid) >= all(select e.empid
from employee ee
where e.did = ee.did
group by ee.empid))
group by dname
The tables I have are
Employee
| EMPID | NAME | SALARY | DID |
--------------------------------
| 1 | kevin | 32000 | 2 |
| 2 | joan | 46200 | 1 |
| 3 | brian | 37000 | 3 |
| 4 | larry | 82000 | 5 |
| 5 | harry | 92000 | 4 |
| 6 | peter | 45000 | 2 |
| 7 | peter | 68000 | 3 |
| 8 | smith | 39000 | 4 |
| 9 | chen | 71000 | 1 |
| 10 | kim | 46000 | 5 |
Division
| DID | DNAME | MANAGERID |
----------------------------------------------
| 1 | engineering | 2 |
| 2 | marketing | 1 |
| 3 | human resource | 3 |
| 4 | Research and development | 5 |
| 5 | accounting | 4 |
Workon
| PID | EMPID | HOURS |
-----------------------
| 3 | 1 | 30 |
| 2 | 3 | 40 |
| 5 | 4 | 30 |
| 6 | 6 | 60 |
| 4 | 3 | 70 |
| 2 | 4 | 45 |
| 5 | 3 | 90 |
| 3 | 3 | 100 |
| 6 | 8 | 30 |
| 4 | 4 | 30 |
| 5 | 8 | 30 |
| 6 | 7 | 30 |
| 6 | 9 | 40 |
| 5 | 9 | 50 |
| 4 | 6 | 45 |
| 2 | 7 | 30 |
| 2 | 8 | 30 |
| 2 | 9 | 30 |
| 1 | 9 | 30 |
| 1 | 8 | 30 |
| 1 | 7 | 30 |
| 1 | 5 | 30 |
| 1 | 6 | 30 |
| 2 | 6 | 30 |
You're very close. What you're trying to do is called a "correlated subquery". You're relating a key from a table you are querying to a key in a query that doesn't contribute to the candidate set, but does act as a filter in your where clause.
The key line in your code that demonstrates this is the line in the NOT EXISTS clause that says:
e.did = ee.did
Instead of trying to do this by comparing aggregate COUNT(...) results, do an outer join between the Employee and Workon tables to find out if there are any employees who aren't doing anything, then find your departments based on those employees not existing for a given department.
Here's an example query using the Oracle standard HR example tutorial tables representing the same join conditions as you have here. You probably have access to these tables wherever you're running the query, and so should anyone else here who might be interested in the answer, so they can run the query without building your tables to play around with the answer. It's a relatively trivial matter to convert the query to your tables, so I'll leave that exercise to you! :)
The final capitalized line in my query below is the join condition that makes this query a correlated subquery, like you tried to do in yours.
select
*
from
hr.departments d
where
not exists
(
select
ee.employee_id
,ee.first_name
,ee.last_name
,dd.department_id
,dd.department_name
,jj.job_id
from
hr.employees ee
,hr.departments dd
,hr.job_history jj
where
ee.department_id = dd.department_id
and ee.employee_id = jj.employee_id (+)
and jj.job_id is null
AND D.DEPARTMENT_ID = DD.DEPARTMENT_ID
)