Can someone explain me how to query these tables to get number of employees in companies for each country they are present in? Number of resulting columns should be 3, Company, Country and Employees. Company and Branch are connected but Country is connected with City so I am not sure how to solve this. Thanks guys, appreciate it!!!
CREATE TABLE country (
id integer NOT NULL PRIMARY KEY,
name varchar NOT NULL,
population integer check(population > 0)
);
CREATE TABLE city (
id integer NOT NULL PRIMARY KEY,
name varchar NOT NULL,
population integer check(population > 0),
country integer NOT NULL REFERENCES country(id)
);
CREATE TABLE company (
id integer NOT NULL PRIMARY KEY,
name varchar NOT NULL
);
CREATE TABLE branch (
company integer NOT NULL REFERENCES company(id),
city integer NOT NULL REFERENCES city(id),
name varchar,
employees integer NOT NULL,
PRIMARY KEY (company, city)
);
This is what I did but I know it is wrong, I tried my combinations but so far nothing was correct!
SELECT
branch.employees,
company.name AS company,
country.name AS country
FROM branch
INNER JOIN company
ON branch.company = company.id
INNER JOIN country
ON city.country = country.id
ORDER BY country;
SELECT
company.name AS company,
country.name AS country,
sum(branch.employees) AS country_employees
FROM branch
JOIN company ON company.id = branch.company
JOIN city ON city.id = branch.city
JOIN country ON country.id = city.country
GROUP BY company.name, country.name
ORDER BY country.name, company.name;
You want to sum over the number of employees per company, for each of the countries they work in. This means that you have to GROUP BY those two fields while you SUM the number employees per branch. You need to use the city table as well, even though you do not display any data from it.
Read up on aggregate functions for more background information.
Related
Just started learning SQL and need help on the Feb 1, 2020 part.
The database has three tables for tracking horse-riding lessons:
Horse with columns:
ID - primary key
RegisteredName
Breed
Height
BirthDate
Student with columns:
ID - primary key
FirstName
LastName
Street
City
State
Zip
Phone
EmailAddress
Lesson Schedule with columns:
HorseID - partial primary key, foreign key references Horse(ID)
StudentID - foreign key references Student(ID)
LessonDateTime - partial primary key
Write a SELECT statement to create a lesson schedule for Feb 1, 2020 with the lesson date/time, student's first and last names, and the horse's registered name. Order the results in ascending order by lesson date/time, then by the horse's registered name. Make sure unassigned lesson times (student ID is NULL) appear in the results.
Hint: Perform a join on the LessonSchedule, Student, and Horse tables, matching the student IDs and horse IDs.
This is what I have; not sure of the correct way to go about it. I've tried using WHERE and AND but get an error or only all NULL first/last names in the table.
SELECT LessonDateTime, FirstName, LastName, RegisteredName
FROM LessonSchedule
LEFT JOIN Student ON LessonSchedule.StudentID = Student.ID
INNER JOIN Horse ON LessonSchedule.HorseID = Horse.ID
ORDER BY LessonDateTime, RegisteredName;
Please try this.
I think it will work.
SELECT LessonDateTime, FirstName, LastName, RegisteredName
FROM LessonSchedule
LEFT JOIN Student ON LessonSchedule.StudentID = Student.ID
INNER JOIN Horse ON LessonSchedule.HorseID = Horse.ID
WHERE LessonDateTime = '2020-02-01'
ORDER BY LessonDateTime, RegisteredName;
Departments Table:
information about the id of each department of a university.
Column Name
Type
id (PK)
int
name
varchar
Students Table:
information about the id of each student at a university and the id of the department he/she studies at.
Column Name
Type
id(PK)
int
name
varchar
department_id
int
I need to find the id and the name of all students who are enrolled in departments that no longer exists.
I wrote queries in two ways, first is
SELECT s.id, s.name
FROM Students s LEFT JOIN Departments d
ON s.department_id = d.id
WHERE d.id IS NULL;
the second query, I changed d.id IS NULL to d.name IS NULL, the runtime increases a lot. I wonder why does this happen?
So I'm having an issue with trying to return records that have two conditions which are not equal.
I have three tables: Person, Student, and Instructor. I'm trying to return a list of persons who are neither students or instructors.
Here are the tables (they are all populated with values that fit all criteria):
CREATE TABLE Person (
Name char (20),
ID char (9) not null,
Address char (30),
DOB date,
Primary key (ID)
);
CREATE TABLE Instructor (
InstructorID char (9) not null references Person (ID),
Rank char (12),
Salary integer,
PRIMARY KEY (InstructorID)
);
CREATE TABLE Student (
StudentID char (9) not null REFERENCES Person (ID),
Classification char (10),
GPA DOUBLE,
MentorID char (9) REFERENCES Instructor (InstructorID),
CreditHours integer,
PRIMARY KEY (StudentID)
);
And here is my answer/query:
SELECT Person.ID, Person.Name, Person.DOB
FROM Person
RIGHT JOIN Student ON Person.ID = Student.StudentID
RIGHT JOIN Instructor ON Person.ID = Instructor.InstructorID
WHERE NOT Person.ID = Student.StudentID AND Person.ID =
Instructor.InstructorID;
Did I screw up something on my joins? I'm not getting any errors, but the query isn't returning anything either. I've tried all joins (left, right, full) to no avail.
Any help is greatly appreciated.
You may use NOT IN to determine if the records are not in both of those tables
SELECT id,
name,
dob
FROM Person
WHERE id NOT IN (SELECT studentid
FROM student)
AND id NOT IN (SELECT instructorid
FROM instructor);
You are pretty close. First, use LEFT JOIN so you keep everything in the first table. Second, use comparisons to NULL to see if there are matches:
SELECT p.ID, p.Name, p.DOB
FROM Person p LEFT JOIN
Student s
ON p.ID = s.StudentID LEFT JOIN
Instructor i
ON p.ID = i.InstructorID
WHERE s.StudentID IS NULL AND i.InstructorID IS NULL;
First and foremost, this is part of an assignment, but I'm trying to get more clarification on how the count() function works when querying a db.
The question is: List the name, SSN and the number of courses the student has taken (courses with the same CourseNumber taken in different quarters are counted as different courses).
I've been querying using this:
SELECT S.Name, S.SSN, COUNT(*)
FROM Student S, Enrollment E
WHERE S.SSN = E.SSN
GROUP BY S.SSN
which seems to return the correct answer, but I'm not sure why. As a result, I can't seem to get the next questions (assuming courses with the same CourseNumber taken in different quarters are considered as one course) correct.
Here are the create table commands so you can see which table holds what info:
CREATE TABLE Student(
SSN INT(9),
Name VARCHAR(20),
Major VARCHAR(30),
PRIMARY KEY (SSN)
);
CREATE TABLE Course(
CourseNumber INT(5),
PrerequisiteCourseNumber INT(10),
CourseTitle VARCHAR(10),
NumberUnits INT(2),
PRIMARY KEY (CourseNumber)
);
CREATE TABLE Section(
CourseNumber INT(5),
Quarter VARCHAR(10),
RoomNumber INT(5),
DayTime VARCHAR(20),
PRIMARY KEY (CourseNumber,Quarter),
FOREIGN KEY (CourseNumber) REFERENCES Course(CourseNumber)
);
CREATE TABLE Enrollment(
SSN INT(9),
CourseNumber INT(5),
Quarter VARCHAR(10),
Grade VARCHAR(1),
PRIMARY KEY (SSN,CourseNumber,Quarter),
FOREIGN KEY (SSN) REFERENCES Student(SSN),
FOREIGN KEY (CourseNumber) REFERENCES Course(CourseNumber),
FOREIGN KEY (Quarter) REFERENCES Section(Quarter)
);
Any pointers?
what you are doing is using old join syntax (pre ansi syntax) where you do a cross join of tables and use the where to turn it into a join. an equivalent query would be this.
SELECT S.Name, S.SSN, COUNT(*)
FROM Student S
JOIN Enrollment E ON S.SSN = E.SSN
GROUP BY S.SSN
Now to answer your question about what the count is doing and stuff..
COUNT() returns a count of every row that is returned.
GROUP BY groups all of the records by a common ground aka your SSN field. so if a student has 5 SSN rows in the table then his count will be 5.
Now for the part you are looking for with course numbers.. you need to JOIN those tables on appropriate fields and add a field to your group by for each quarter
aka add to the previous code..
WHERE E.quarter = whatever_quarter_you_want
you can add more to this query if you need to. but add data to your question if you want a more full answer.
Your current query is:-
SELECT S.Name, S.SSN, COUNT(*)
FROM Student S
INNER JOIN Enrollment E
ON S.SSN = E.SSN
GROUP BY S.SSN
What this is doing is joining student to enrollment, so giving multiple rows for each student, one for each course / quarter they are enrolled on. It is then grouped by SSN (student number?) to count up the number of course / quarters they are enrolled on. You should really group by S.Name as well (while MySQL won't object, most flavours of SQL would).
Note that COUNT(*) counts the number of rows. You could use COUNT(E.CourseNumber) which would count the number of rows where course number is not null. Not really useful here, but can be useful with LEFT OUTER JOINs. You can also use COUNT(DISTINCT CourseNumber) to count the number of unique non null course numbers for the student.
A LEFT OUTER JOIN might also be better as this would enable you to return 0 as the counts for students who exist but who are not enrolled in any courses:-
SELECT S.Name, S.SSN, COUNT(DISTINCT E.CourseNumber)
FROM Student S
LEFT OUTER JOIN Enrollment E
ON S.SSN = E.SSN
GROUP BY S.Name, S.SSN
SELECT S.Name, S.SSN, COUNT(*)
FROM Student S, Enrollment E, Section Sec, Course C
WHERE S.SSN = E.SSN AND E.CourseNumber = Sec.CourseNumber
AND Sec.CourseNumber = C.CourseNumber AND Sec.Quarter like E.Quarter
GROUP BY S.Name, S.SSN
I just recently started learning how to write SQL queries, and I have a lot to learn and a lot of questions, mainly regarding defining conditions for an SQL query. I have 3 tables (with fields listed below):
Employee:
EmployeeID, Name, DoB, StartDate
Salary:
SalaryID, DataPaid, AmountPaid, EmployeeID
Address:
AddressID, Address, City, EmployeeID
Now I would like to know how to:
1. Count the number of employees that live in the city of London.
My attempt:
SELECT COUNT(City) AS EmployeeID FROM Address
WHERE City='London';
2. Add up the 'AmountPaid' values for all employees from the city of London.
My attempt:
SELECT SUM(AmountPaid) AS TotalPaid FROM Salary
WHERE City='London';
3. Display data for all employees that started in 2012 (have a 'Start Date' containing 2012). Not sure where to begin with this!
4. Delete all records where the employee 'Name' field is empty/null.
My attempt:
DELETE FROM Employee
WHERE Name=NULL;
Am I doing something wrong with my attempts? Any help would be appreciated.
THANK YOU!
In SQL Server (T-SQL), you cannot test a value for NULL using '='. It must be as follows:
Delete From Employee Where Name IS NULL
Also i would check for empty names:
DELETE FROM Employee where Name IS NULL OR Name=''
As for the point 3:
SELECT * FROM Employee WHERE Year(StartDate)=2012
As for the point 2, the table Salary does not have an City column. You need to join with Employee table like this:
SELECT SUM(AmountPaid) AS TotalPaid FROM Salary SA inner join Employee Em on Em.EmployeeID=SA.EmployeeID WHERE Em.City='London';
Smells a bit like homework. Anyway:
(1) count of employees in the city of London
First statement seems correct to me, isn't it? But the alias confused me a bit as it says EmployeeID but returned value is the count of employees.
(2) total amount paid for employees in the city of London
This wouldn't work with your statement because table Salary has no field City. You'll need a join here:
select sum(AmountPaid) as TotalPaid
from Salary s
join Address a on s.EmployeeID = a.EmployeeID
where a.City = 'London'
(3) employees started in 2012
Here you can use YEAR function to extract the year out of the date:
select *
from Employee
where Year(StartDate) = 2012
(4) delete unnamed employees
Taken from the solution of #ericpap (for the sake of completeness):
delete from Employee
where Name is NULL
or Name = ''
I would do it like this - it includes a test whereby you make tables and data to help you see how it works;
I assume a employee has only one address, but recieves multiple payments and while it may not be necessary to join from the employee tables in your example - it shows how the relationships between employees and the other tables work, which may help you understand the relational model better.
--Make the Tables
CREATE TABLE dbo.Employee
(
EmployeeID BIGINT PRIMARY KEY NOT NULL,
Name VARCHAR(50),
DoB DATE,
StartDate DATE
)
CREATE TABLE dbo.Salary
(
SalaryID BIGINT PRIMARY KEY NOT NULL,
DatePaid DATE, -- I think you mean DatePaid and not DataPaid
AmountPaid MONEY,
EmployeeID BIGINT
)
CREATE TABLE dbo.Address
(
AddressID BIGINT PRIMARY KEY NOT NULL,
[Address] VARCHAR(max),
City VARCHAR(200),
EmployeeID BIGINT
)
-- Put in some Test Data
INSERT INTO dbo.Employee (EmployeeID,Name, DoB, StartDate)
VALUES (1,'Bill Gates','19551028','20121014'),
(2,'Larry Ellison','19440817','20140101')
INSERT INTO dbo.Address (AddressID,[Address], City, EmployeeID)
VALUES (1,'15 Microsoft House','New York',1),
(2,'23 Oracle Flats','London',2)
INSERT INTO dbo.Salary(SalaryID, DatePaid, AmountPaid, EmployeeID)
VALUES (1,Getdate(),5000.53,1),
(2,'20140201',10000.23,2),
(3,'20140301',10000.23,2)
-- Queries;
--Count the number of employees that live in the city of London.
SELECT COUNT(Distinct E.EmployeeID) as Count_London
FROM dbo.Employee E
INNER JOIN dbo.[Address] A
ON E.EmployeeID = A.EmployeeID
WHERE A.City = 'London'
-- Result = 1
-- 2. Add up the 'AmountPaid' values for all employees from the city of London
--Total Amount
SELECT Sum(S.AmountPaid) as TotalPaid
FROM dbo.Employee E
INNER JOIN dbo.[Address] A
ON E.EmployeeID = A.EmployeeID
LEFT JOIN dbo.Salary S
ON E.EmployeeID = S.EmployeeID
WHERE A.City = 'London'
-- Result = 20000.46 (2 x 10000.23)
--split by employee;
SELECT E.EmployeeID,E.Name,Sum(S.AmountPaid) as TotalPaid
FROM dbo.Employee E
INNER JOIN dbo.[Address] A
ON E.EmployeeID = A.EmployeeID
LEFT JOIN dbo.Salary S
ON E.EmployeeID = S.EmployeeID
WHERE A.City = 'London'
GROUP BY E.EmployeeID, E.Name
--3. Display data for all employees that started in 2012
SELECT *
FROM dbo.Employee E
INNER JOIN dbo.[Address] A
ON E.EmployeeID = A.EmployeeID
LEFT JOIN dbo.Salary S
ON E.EmployeeID = S.EmployeeID
WHERE StartDate >= '20120101' AND StartDate < '20130101'
-- result = all bill gates fields
-- 4. Delete all records where the employee 'Name' field is empty/null.
DELETE FROM dbo.Employee WHERE EmployeeID IS NULL
you might want to delete where the employeeID is null from all the tables if it is possible to have records in there
This wasn't addressed in the other answers:
Count the number of employees that live in the city of London
Your attempt below will get you the right answer only if there is a different employee per row.
SELECT COUNT(City) AS EmployeeID FROM Address
WHERE City='London';
If your Address table looks like it does below, using the query you wrote, you would get 3 employees (but we can see from the table there are only 2 distinct EmployeeID's so thus only 2 employees).
AddressID, Address, City, EmployeeID
1, 1 Main St, London, 1
2, 2 Main St, London, 2
3, 3 Main St, London, 1
What you should do is count the number of distinct EmployeeID's. Each of these EmployeeID's identifies a unique employee. Thus your query should look like this:
SELECT COUNT(DISTINCT EmployeeID) AS EmployeeID FROM Address
WHERE City='London';
That will get you the correct answer every time regardless of what your table looks like.