SQL getting empty fields from other table - mysql

i am working with views for the first time.
I can see the records from table Student in the view, but the records from table Course are not shown getting NULL everywhere.
Here are the tables I created:
-- Tabel StudentCourse maken
CREATE TABLE StudentCourse
(
StudentCourse int NOT NULL,
CourseId int NOT NULL,
StudentId int NOT NULL
)
-- DROP table StudentCourse
-- Tabel Course maken
CREATE TABLE Course
(
CourseId int NOT NULL,
Name varchar(255) NOT NULL,
StartDate date NOT NULL,
EndDate date NOT NULL,
Period int NOT NULL,
IsWeekEnd bit NOT NULL,
IsActive bit NOT NULL
)
-- DROP table Course
-- Tabel Student maken
CREATE TABLE Student
(
StudentId int NOT NULL,
Name varchar(255) NOT NULL,
Age int NOT NULL,
Address varchar(255) NOT NULL,
Registered datetime NOT NULL,
IsActive bit NOT NULL,
Description varchar(255) NOT NULL
)
-- DROP table Student
And here is the view i created
CREATE VIEW V AS (
SELECT s.StudentId,s.Name,c.CourseId,c.StartDate FROM
Student s
LEFT JOIN
Course c
ON
s.Name=c.Name
);
Thanks for your time!

There are no Courses with the same name as names from students. You need to LEFT JOIN Student on StudentCourse and INNER JOIN StudentCourse on Course.
SELECT s.StudentId,s.Name,c.CourseId,c.StartDate
FROM Student s
LEFT JOIN StudentCourse sc ON s.StudentId = sc.StudentId
INNER JOIN Course c ON sc.CourseId = c.CourseId

Related

mysql subquery COUNT with WHERE clause confusion

I been mashing buttons all day but cant get this query to work. I have 3 tables students, courses and enrollment table that shows which classes the students have enrolled in
The query needs to retrieve all courses having at least 2 students enrolled which is ordered by course with the greatest number of students
I worked out how to retrieve the count of enrollments per class but having trouble filtering enrollments to >= 2 students
-- coursetable -----------------------------
CREATE TABLE StudentTable(
studentID VARCHAR(255) NOT NULL,
firstName VARCHAR(255) NOT NULL,
LastName VARCHAR(255) NOT NULL,
DOB DATE NULL,
CONSTRAINT pk_studentTable PRIMARY KEY(studentID)
);
-- coursetable -----------------------
CREATE TABLE CourseTable(
courseID VARCHAR(255) NOT NULL,
courseName VARCHAR(255) NOT NULL,
hoursPerWeek int(11) NULL,
startDate DATE NULL,
CONSTRAINT pk_courseTable PRIMARY KEY(courseID)
);
-- enrolment table --
CREATE TABLE EnrolmentTable(
studentID VARCHAR(255) NOT NULL,
CourseID VARCHAR(255) NOT NULL,
CONSTRAINT pk_enrolmentTable PRIMARY KEY(studentID, CourseID)
);
this is the query i can do showing enrollments of all classes but it shows one class having only 1 student enrolled. I need it to only display classes with => 2 enrollments
SELECT ct.CourseName AS Course_Name, COUNT(st.studentID) AS Students_Enrolled
FROM EnrolmentTable et
INNER JOIN courseTable ct ON ct.courseID = et.courseID
INNER JOIN studentTable st ON st.studentID = et.studentID
GROUP BY et.courseID;
I need to use a subquery right? but not sure how
You can use HAVING to filter the result
SELECT ct.CourseName AS Course_Name, COUNT(st.studentID) AS Students_Enrolled
FROM EnrolmentTable et
INNER JOIN courseTable ct ON ct.courseID = et.courseID
INNER JOIN studentTable st ON st.studentID = et.studentID
GROUP BY et.courseID
HAVING Students_Enrolled> 1
ORDER BY Students_Enrolled DESC

MySQL: How to show all courses available and in another column in which ones a specific user is already enrolled in?

I want to show all the courses in the MySQL database, and show in which ones a specific use is enrolled in.
My database structure is like this:
CREATE TABLE usuarios(
userID int unsigned not null auto_increment primary key,
userName char(50) null,
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE cursos (
cursoID int unsigned not null auto_increment primary key,
nombreCurso char(100) not null,
estadoCurso char(50) not null,
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE cursosUsuarios (
cursosUsuariosID int unsigned not null auto_increment primary key,
userID int not null,
cursoID int not null,
userHabilitado int(1) not null DEFAULT '0',
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
If I do have this information:
UserID Alfa is enrolled in cursoID A and B
UserID Beta is enrolled in cursoID A and C
UserID Gamma is enrolled in cursoID C
UserID Delta is enrolled in cursoID D
UserID Epsylon is enrolled in cursoID C and E
How can I show a list of all courses but showing in that list what courses does belong user Alfa?
Like this:
Curso ID ========== User ID
A ========== Alfa
B ========== Alfa
C ========== NULL
D ========== NULL
E ========== NULL
Since the output lists all the courses where a particular user might not take the course so that you need to make a left join among cursos table and cursosUsuarios, usuarios tables while making the cursos table as the left table.
SELECT
C.nombreCurso,
U.userName
FROM cursos C
LEFT JOIN cursosUsuarios CU ON CU.cursoID = C.cursoID
LEFT JOIN usuarios U ON U.userID = CU.userID AND U.userID = <PUT THE USERID OF Alfa here>;

How to show a list of items NOT IN a certain MySQL table? This query isn't working

I have a list of courses (that can be open or closed) and a list of users (that can be enrolled into one or more courses).
I have three tables: usuarios (for users), cursos(for courses) and cursosUsuarios (that links the two to know who's enrolled where).
I want to show a list of available courses where an specific user (ie. UID 18) is NOT enrolled.
I'm trying this query, that's not working:
SELECT cursos.cursoID, cursos.nombreCurso, cursos.cursoFechaInicio,
cursos.modalidadCurso, cursos.estadoCurso,
cursosUsuarios.userID, cursosUsuarios.cursoID
FROM cursos
LEFT JOIN cursosUsuarios ON cursos.cursoID = cursosUsuarios.cursoID
WHERE cursosUsuarios.userID NOT IN (
SELECT cursosUsuarios.userID
FROM cursosUsuarios
)
AND estadoCurso='abierto'
AND cursosUsuarios.userID = 18
These are my tables:
CREATE TABLE cursos (
cursoID int unsigned not null auto_increment primary key,
nombreCurso char(100) not null,
cursoFechaInicio char(10) null,
modalidadCurso char(50) not null,
estadoCurso char(50) not null,
)
CREATE TABLE usuarios(
userID int unsigned not null auto_increment primary key,
)
CREATE TABLE cursosUsuarios (
cursosUsuariosID int unsigned not null auto_increment primary key,
userID int not null,
cursoID int not null
)
Move that condition from WHERE to JOIN ON clause like
FROM cursos LEFT JOIN cursosUsuarios
ON cursos.cursoID = cursosUsuarios.cursoID
AND cursosUsuarios.userID <> 18
WHERE estadoCurso='abierto'
I believe your problem is the LEFT JOIN. If you turn it into an INNER JOIN (e.g., just "JOIN"), that should accomplish what you want.
This will return all courses that are 'abierto', where userID 18 and cursos does not exist in the cursosUsuarios table, using alias's to clean things up a little bit.
SELECT c.cursoID, c.nombreCurso, c.cursoFechaInicio, c.modalidadCurso, c.estadoCurso, cu.userID, cu.cursoID
FROM cursos c
LEFT JOIN cursosUsuarios cu ON c.cursoID = cu.cursoID AND cu.userID = 18
WHERE cu.cursosUsuariosID is null
AND c.estadoCurso='abierto'

MYSQL SELECT query: How to concatenate 4 tables with AND and OR conditions?

I have four MySQL tables:
usuarios (have the list of all users and their personal information)
roles (have the list of available roles in the site, that determines their permissions)
rolesUsuarios (links each user with their roles. They can have more than one)
cursos (have the list of courses of the site with each course description)
cursosUsuarios (links each user with all the courses where they are enrolled)
I want to make a SELECT query that shows me for a specific user, all their personal information, the roles he has and the courses where he's enrolled.
I've created this query that does work:
SELECT usuarios.userID, usuarios.userEmail, usuarios.userApellido, usuarios.userNombres,
usuarios.userDNI, usuarios.userFechaGeneracion,
rolesUsuarios.userID, rolesUsuarios.nombreRol,
cursosUsuarios.userID, cursosUsuarios.cursoID,
cursos.cursoID, cursos.nombreCurso, cursos.cursoYear, cursos.cursoMes,
cursos.modalidadCurso,
GROUP_CONCAT(cursos.nombreCurso, ':', cursosUsuarios.cursoID ORDER BY cursosUsuarios.cursoID SEPARATOR ',') AS 'cursos'
FROM usuarios JOIN rolesUsuarios JOIN cursosUsuarios JOIN cursos
WHERE usuarios.userID='10'
AND rolesUsuarios.userID = usuarios.userID
AND cursosUsuarios.userID = usuarios.userID
AND cursosUsuarios.cursoID = cursos.cursoID
GROUP BY usuarios.userID
The problem is that if the user isn't enrolled in any course, it won't show any result. How may I do that?
These are each tables structure:
CREATE TABLE roles(
roleID int unsigned not null auto_increment primary key,
nombreRol char(50) not null
);
CREATE TABLE usuarios(
userID int unsigned not null auto_increment primary key,
userEmail char(50) null,
userApellido char(50) null,
userNombres char(50) null,
userDNI int(10) null,
userPass char(65) null,
userFechaGeneracion char(10) null
);
CREATE TABLE rolesUsuarios (
rolesUsuariosID int unsigned not null auto_increment primary key,
userID int not null,
nombreRol char(50) not null
);
CREATE TABLE cursos (
cursoID int unsigned not null auto_increment primary key,
nombreCurso char(100) not null,
cursoYear int(4) not null,
cursoMes char(3) not null,
cursoFechaInicio char(10) null,
modalidadCurso char(50) not null
);
CREATE TABLE cursosUsuarios (
cursosUsuariosID int unsigned not null auto_increment primary key,
userID int not null,
cursoID int not null
);
I think something like this will work:
SELECT usuarios.userID, usuarios.userEmail, usuarios.userApellido, usuarios.userNombres,
usuarios.userDNI, usuarios.userFechaGeneracion,
rolesUsuarios.userID, rolesUsuarios.nombreRol,
cursosUsuarios.userID, cursosUsuarios.cursoID,
cursos.cursoID, cursos.nombreCurso, cursos.cursoYear, cursos.cursoMes,
cursos.modalidadCurso,
GROUP_CONCAT(cursos.nombreCurso, ':', cursosUsuarios.cursoID ORDER BY cursosUsuarios.cursoID SEPARATOR ',') AS 'cursos'
FROM usuarios LEFT JOIN rolesUsuarios
ON usuarios.userID = rolesUsuarios.userID
LEFT JOIN cursosUsuarios
ON usuarios.userID = cursosUsuarios.userID
LEFT JOIN cursos
ON cursosUsuarios.cursoID = cursos.cursoID
WHERE usuarios.userID='10'
GROUP BY usuarios.userID;
Also, if you are selecting a single userID in the WHERE clause there is no need for the GROUP BY userID line.

Choosing applicants for positions via a MySQL query

I have the following MySQL tables. They represent CS courses at a school and applicants to be a TA (teaching assistant) for specific courses.
I want to create a query that will print the "best" applicant for each course. The constraints for the best applicant are:
Applicants with Applicants.level = 7 are matched first.
Applicants with ApplicantsToCourses.returning = true are chosen second.
All other applicants are matched without further discrimination.
The table definitions are:
CREATE TABLE Courses (
course_number SMALLINT(3) UNSIGNED NOT NULL,
course_section SMALLINT(1) UNSIGNED NOT NULL,
name CHAR(30) NOT NULL,
instructor CHAR(30),
lab_time CHAR(30),
PRIMARY KEY(course_number, section),
FOREIGN KEY(course_number, section) REFERENCES ApplicantsToCourses(course_number, course_section)
)
CREATE TABLE Applicants (
student_id CHAR(10) NOT NULL,
name CHAR(30),
email CHAR(30),
gpa DECIMAL(4,3) UNSIGNED,
level CHAR(2),
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(student_id),
FOREIGN KEY(student_id) REFERENCES ApplicantsToCourses(student_id),
CHECK(gpa <= 4.000)
)
CREATE TABLE ApplicantsToCourses (
student_id CHAR(10) NOT NULL,
returning BOOLEAN DEFAULT FALSE NOT NULL,
course_number SMALLINT(3) UNSIGNED NOT NULL,
course_section SMALLINT(1) UNSIGNED NOT NULL,
PRIMARY KEY(student_id, course_number, course_section),
FOREIGN KEY(student_id) REFERENCES Applicants(student_id),
FOREIGN KEY(course_number, course_section) REFERENCES Courses(course_number, course_section)
)
My attempt at a query was . . .
select a.student_id, ac.course_number, ac.course_section
from Applicants a, ApplicantsToCourses ac, Courses c
where a.student_id = ac.student_id and ac.course_number = c.course_number and ac.course_section = c.course_section
order by a.level, ac.returning desc
. . . but that certainly doesn't have the correct logic.
You can use the following pseudo code to create some temporary tables that should help you reach your final solution.
SELECT *
FROM Applicants APP
JOIN ApplicantsToCourses ATC ON ATC.student_id = APP.student_id
JOIN Courses COU ON COU.number = ATC.course_number AND COU.section = ATC.course_section
WHERE APP.level = 7
SELECT *
FROM Applicants APP
JOIN ApplicantsToCourses ATC ON ATC.student_id = APP.student_id
JOIN Courses COU ON COU.number = ATC.course_number AND COU.section = ATC.course_section
WHERE ATC.returning = true