I'm new here on the site, I'm learning databases independently, and there's a question I've been trying for a long time, and I decided to ask it here
The question has such a database:
Person (p-id, name, title, hourly-rate, title)
Topics (t-name, description)
Workshops (p-id, t-name, hourly-credit)
Employees (e-id, name, address, mobile)
EmpTraining (e-id, p-id, t-name)
Persona - The lecturer has a unique ID, name, degree, cost per hour
Topics - the topics in which workshops are delivered. Each topic has a unique name (time management, budget management, etc.) and description.
Workshop - A workshop delivered by a specific lecturer on a specific topic. (Several lecturers can deliver a workshop on the same topic and a lecturer can deliver workshops on different topics) Each workshop is defined as the number of hours that entitle the employee to the training allowance.
Employee - The employee has a unique ID, address and telephone name.
EmpTraining - Each employee is documented in all the workshops he has taken
Example of the database I built, I want to point out that the example here is from a test I failed, the database itself I added is just an example, it does not belong to the exercise itself, but that way it is easier for me to explain, and that way easier to understand.
https://www.db-fiddle.com/f/wrDLMHhsquiFQmZT7uS3Z9/0
I need to write it in code in SQL, two things:
Return the names of the employees who have undergone at least the same series of workshops as the outstanding employee whose employee number is 100.
In this question I have to return the names of all the workers, who did all the workshop that a worker with number 100 did
i try to write, i dont thing that is right, because i am not sure how to select same series of workshops:
select name
from Persona as p1, Workshops as w1
where exist {
select *
from Persona as p2, Workshops as w2
where p2.p-id = 100 AND w1.p-is != w2.p-id and w1.t-name = w2.t-name
}
Return the names of all the employees who have accumulated the number of hours of entitlement to training higher than that of the outstanding employee whose employee number is 100.
In this question I have to return the names of all the employees, that the number of hours they did for training is greater than the hours that employee number 100 did
I did not make it 2, was hard to me.
I would be very happy to help, I have been trying to do this for two weeks, thank you very much.
I want to point out that I do not have the tables with the data, this is a question from a test I had, I do not know how to make tables for it, I need an answer that is similar to the solution, like a pseudo-code
As per your example, I'm expecting by Employees you mean Employees table and by no of hours they did you mean hourly_credit in Workshop table, then below are the queries -
1st Query Can be like -
SELECT e.e_id FROM Employees e inner join EmpTraining et on e.e_id = et.e_id where et.t_name in (
SELECT t_name FROM EmpTraining where e_id = 100
)
GROUP BY et.e_id
having count(DISTINCT et.t_name) >= (SELECT count(DISTINCT t_name)
FROM EmpTraining where e_id = 100);
Here first I'm filtering rows on the basis of workshop name of employee id 100, using below sub query
SELECT t_name FROM EmpTraining where e_id = 100
Then if we group the result set and then compare distinct count with the distinct count of workshops of employee hundred we can get the employees set we want
Note: Result will contain employee with id - 100 as well to exclude it from the result we can add another condition in where like -
AND e.e_id != 100
2 nd Query
SELECT any_value(e.name) as name
FROM Employees e inner join EmpTraining et on e.e_id = et.e_id inner join Workshops w on et.t_name = w.t_name
GROUP BY et.e_id
having sum(w.hourly_credit) > (
SELECT sum(w.hourly_credit)
FROM Workshops w inner join EmpTraining etg on etg.t_name = w.t_name
where etg.e_id = 100
);
Here I'm grouping rows of EmpTraining on the basis of e_id and comparing sum of hourly_credit with the sum of hourly_credit of employee id 100 EmpTrainings
Related
Okay so this is my best attempt at making a query. It currently executes but returns nothing the other attempts have not worked.
The joins are wrong I believe and I'm not sure how to fix them or do this right
In this query I am trying to get the activity details with staff assigned to those activities matching all conditions below.
The staff and activities are linked in the Allocation table with a Staff ID assigned to an Activity ID there.
--Teach at least 2 modules during 2019 in a certain campus
The staffID must occur at least twice in the Teach table at the field StaffID
The spaID 5 or 6 would correspond to the campus so teach two modules at this time and ID.
--Supervise more than 1 colleagues
This is in the staff table with SupervisorID being a foreign key of StaffID in the same table.
So the Staff ID allocated to the activity needs to supervise more than one colleague with their ID appearing in SupervisorID more than once.
--The related activity is internal one
The activity is internal if it equals to 1.
So to sum it up the activity details should only appear in the query results if it has staff matching all the conditions above
SELECT Activity.AcID, Activity.Title, Activity.CaID, Activity.Internal, Activity.BuID, Budget.Amount FROM Activity
INNER JOIN Budget ON Activity.AcID = Budget.BuID
INNER JOIN Allocation ON Activity.AcID = Allocation.AcID
INNER JOIN Staff ON Allocation.StaffID = Staff.StaffID
INNER JOIN Teach ON Allocation.StaffID = Teach.StaffID
WHERE Activity.Internal=1 AND
Allocation.StaffID IN (
SELECT Staff.SupervisorID
FROM Staff
GROUP BY StaffID
HAVING COUNT(Staff.SupervisorID=Allocation.StaffID) >1)
AND Allocation.StaffID IN (
SELECT Teach.StaffID
FROM Teach
WHERE Teach.Year='2019' AND Teach.SpaID=5 OR 6
GROUP BY Teach.StaffID
HAVING COUNT(Allocation.StaffID=Teach.StaffID) >=2);
Table details are below if you want to look at them for more details
Table Activity -- AcID, Title, CaID, BuID, Status, Started, Ended Internal
Table Allocation -- StaffID, AcID
Table Budget -- BuID, Amount, Approver, Payee, Status
Table Campus -- CaID, Address, GmName, Country, Status
Table Classroom -- RmID, Capacity, CaID, Location, Type, Status
Table Module -- ModuleID, Module Name, DeptID, Programme, TMode, Date_of_Firstoffer
Table SpaceAssign -- SpaID, RmID, TID, Manager, Approved
Table Staff -- StaffID, Title, FirstName, LastName, DeptID, CaID, Joined, LeftD, Current, Salary, ContractType, SupervisorID
Table Teach -- TID, ModuleID, StaffID, SpaID, Semester, Year
I have tried my best to explain this well sorry for any confusion.
Without data It's very tough to find a solution. Please try this:
SELECT Activity.AcID, Activity.Title, Activity.CaID, Activity.Internal, Activity.BuID, Budget.Amount FROM Activity
INNER JOIN Budget ON Activity.AcID = Budget.BuID
INNER JOIN Allocation ON Activity.AcID = Allocation.AcID
INNER JOIN Staff ON Allocation.StaffID = Staff.StaffID
INNER JOIN Teach ON Allocation.StaffID = Teach.StaffID
WHERE Activity.Internal=1 AND
Allocation.StaffID IN (
SELECT Staff.SupervisorID
FROM Staff
GROUP BY SupervisorID
HAVING COUNT(*) >1)
AND Allocation.StaffID IN (
SELECT Teach.StaffID
FROM Teach
WHERE Teach.Year='2019' AND Teach.SpaID=5 OR 6
GROUP BY Teach.StaffID
HAVING COUNT(*) >=2);
It is hard to tell without having access to the data but you can try to change the inner joins to left joins and also:
This
WHERE Teach.Year='2019' AND Teach.SpaID=5 OR 6
Should be
WHERE Teach.Year='2019' AND (Teach.SpaID=5 OR Teach.SpaID=6)
This looks incorrect as well:
INNER JOIN Budget ON Activity.AcID = Budget.BuID
Should be:
INNER JOIN Budget ON Activity.BuID = Budget.BuID
I have three tables: Students, Friends, and Packages. Students contain two columns: ID and Name. Friends contain two columns: ID and Friend_ID (ID of the ONLY best friend). Packages contain two columns: ID and Salary (offered salary in $ thousands per month)
I have to write a query to output the names of those students whose best friends got offered a higher salary than them. Names must be ordered by the salary amount offered to the best friends. It is guaranteed that no two students got the same salary offer.
Here is my tables:
Student Table Friends Table Packges Table
And the output should like this:Output Table
First join all 3 table with their id while you will get every name with their friend id. Now you have join that friend id with packages id while you will get friends salary. finally filter FRIEND_SALARY>SALARY .
I use oracle syntax here. hope will work fine in mysql also.
select TMP2.NAME name
from (SELECT TMP1.NAME,
PP.ID,
TMP1.SALARY salary,
TMP1.FRIEND_ID,
PP.SALARY friend_salary
FROM packages pp,
(SELECT *
FROM students s, friends f, packages p
WHERE S.ID = F.ID
AND S.ID = P.ID) tmp1
WHERE PP.ID = TMP1.FRIEND_ID) tmp2
where TMP2.FRIEND_SALARY>TMP2.SALARY
I am having a major problem joining 5 tables because each table only has 1 column in common with only 1 other table.
Here are my tables and columns in each table:
TABLE (COLUMNS)
person (person_id, first_name, last name)
building (building_id, building_name)
room (room_id, room_number, building_id, capacity)
meeting (meeting_id, room_id, meeting_start, meeting_end)
person_meeting (person_id, meeting_id)
OK, now here is what I am trying to do (pasted from a homework assignment):
Construct the SQL statement to find all the meetings that person_id #1 has to attend. Display the following columns:
Person’s first name
Person’s last name
Building name
Room number
Meeting start date and time
Meeting end date and time
Now I know how to join 2 tables but I have no idea how to pull info from 5 different tables like this.
I tried looking up how to do this and it just says to do a UNION command, and I am just learning and have yet to cover that.
As UNION is used to combine the result from multiple SELECT statements into a single result set, you don't need it for this scenario. You have to join all the tables one by one based on their Id.
SELECT P.First_Name, P.Last_Name, B.Building_name, R.Room_Number,
M.Meeting_Start, M.Meeting_End FROM Person P
JOIN Person_Meeting PM ON P.Person_Id = PM.Person_Id
JOIN Meeting M ON PM.Meeting_Id = M.Meeting_Id
JOIN Room R ON M.Room_Id = R.Room_Id
JOIN Building B ON R.Building_Id = B.Building_Id
WHERE P.Person_Id = 1
I'm trying to calculate the amount of students from each course, but the amount JOINs required stumbles me a bit.
Tables: student, group and course
students quantity was taken from the group table
SELECT id, SUM(`students quantity`) AS students_all FROM course
JOIN student ON student.group = course.id
JOIN group ON group.`students quantity`=student.id
GROUP BY student.course
ORDER BY `students_all` DESC
What confuses me is this part: I know, I'm doing something wrong, but I can't figure out what exactly
SUM(`students quantity`) AS students_all FROM course
JOIN student ON student.group = course.id
JOIN group ON group.`students quantity`=student.id
The result I have is the single course.id displayed and students_all having all the students overall, instead of the all students from specific course.
What I need to recieve from the query
course.id: 1 2 3 4
students_all: 7 7 6 7
What I get
course.id: 1
students_all: 27
Since I have Russian inteface, I'll post samples this way, to avoid confusion
Group
Student (excluding all the irrelevant data)
As for the course table: the only relevant column there is ID which range is 1-4
It's very late reply of mine, but I solved it myself. No need to answer!
How would I list the students who started later than start year of student with id = 8871?
This is what I have so far:
SELECT sid s1
FROM Student
WHERE s1.started <= sid = '8871';
I went to this link for some reference but I'm still having issues:
Query comparing dates in SQL
Student Table has:
Student (Lastname, Firstname, SID, Started)
any help would be great
I'd use a self join where one side of the join contains the students you want and the the reference student 8871:
SELECT a.*
FROM student a
JOIN student b ON b.sid = '8871' AND a.started > b.started