Split MySQL and compare it - mysql

I have a problem that I don't know how to resolve it, I am a begginer in SQL.
I want to display the first name of all students that have the same FirstName as the teachers name, In the database the teacher's name is a single field but contains 2 logical fields ( FirstName and LastName)
This is my database format
CREATE TABLE Faculty (
Id INT NOT NULL PRIMARY KEY AUTO_INCREMENT
,NAME VARCHAR(50)
,Address VARCHAR(60)
,YearFounded YEAR
,Dean VARCHAR(50)
);
CREATE TABLE Specialty (
Id INT NOT NULL PRIMARY KEY auto_increment
,IdFaculty INT (11) NOT NULL
,NAME VARCHAR(50)
,FOREIGN KEY (IdFaculty) REFERENCES Faculty(Id)
);
CREATE TABLE Course (
Id INT NOT NULL PRIMARY KEY auto_increment
,IdSpecialty INT NOT NULL
,NAME VARCHAR(50)
,TeachingYear INT
,Semester INT
,Professor VARCHAR(50)
,< -- TEACHER
FOREIGN KEY (IdSpecialty) REFERENCES Specialty(Id)
);
CREATE TABLE Student (
Id INT NOT NULL PRIMARY KEY auto_increment
,< -- STUDENT
IdFaculty INT NOT NULL
,IdSpecialty INT NOT NULL
,CurrentYear INT
,StudyGroup VARCHAR(10)
,Semester INT
,Scholarship VARCHAR(2)
,FOREIGN KEY (IdFaculty) REFERENCES Faculty(Id)
,FOREIGN KEY (IdSpecialty) REFERENCES Specialty(Id)
);
CREATE TABLE StudentData (
Id INT NOT NULL PRIMARY KEY
,CNP CHAR(13)
,FirstName VARCHAR(30)
,LastName VARCHAR(30)
,Father VARCHAR(50)
,Mother VARCHAR(50)
,Address VARCHAR(200)
,Nationality VARCHAR(50)
);
CREATE TABLE Grade (
Id INT NOT NULL PRIMARY KEY auto_increment
,IdStudent INT NOT NULL
,IdCourse INT NOT NULL
,Grade INT
,ExamDate DATE
,FOREIGN KEY (IdStudent) REFERENCES Student(Id)
,FOREIGN KEY (IdCourse) REFERENCES Course(Id)
);

Considering that Course.Professor field contains the professor firstname and lastname, I would use this query :
select sd.FirstName from StudentData sd
LEFT JOIN Student s on sd.Id = s.Id
LEFT JOIN Specialty special on s.IdSpecialty = special.Id
LEFT JOIN Course c on special.Id = c.IdSpecialty
WHERE c.Professor = CONCAT(sd.FirstName, ' ', sd.LastName)
EDIT:
If you only want students that have the same FirstName (not lastname) as the professor and if the professor field contains values like "Jacques Dupont" (for example) where Jacques is FirstName and Dupont is LastName then try this (using SUBSTRING_INDEX function to get the professor's FirstName):
select sd.FirstName from StudentData sd
LEFT JOIN Student s on sd.Id = s.Id
LEFT JOIN Specialty special on s.IdSpecialty = special.Id
LEFT JOIN Course c on special.Id = c.IdSpecialty
WHERE SUBSTRING_INDEX(c.Professor,' ',1) = sd.FirstName

Related

Nested query in a view is giving me CHECK OPTION on non-updatable view

CREATE VIEW Res_borrow
AS
SELECT *
FROM borrowing
WHERE mem_id IN (
SELECT mpd.mem_id
FROM (
SELECT mem_id, COUNT(*) AS no_curr_bks
FROM borrowing
WHERE borrowing.ret_date IS NULL
GROUP BY borrowing.mem_id
)Y
RIGHT JOIN mpd ON y.mem_id = mpd.mem_id
WHERE y.no_curr_bks < mpd.nob OR y.no_curr_bks IS NULL
)
WITH CHECK OPTION;
I tried to create such a view but i am getting error
Here is the schema of db
CREATE TABLE MEMBER
(
mem_id INT PRIMARY KEY,
NAME VARCHAR(100) NOT NULL,
pass VARCHAR(12) NOT NULL,
CHECK(CHAR_LENGTH(pass)>7),
ph_no CHAR(11) NOT NULL,
gender VARCHAR(10) NOT NULL,
CHECK(gender='Female' OR gender='Male'),
address VARCHAR(50) NOT NULL,
age INT NOT NULL,
email VARCHAR(50) NOT NULL,
pkg_id INT DEFAULT 0,
FOREIGN KEY (pkg_id) REFERENCES packages(pkg_id)
)
create table mpd --Member Package Details
(
mem_id int primary key foreign key references member(mem_id),
nob int not null default 2,
dur int not null default 14
)
create table borrowing
(
bor_id int primary key,
mem_id int foreign key references member(mem_id) not null,
book_id int foreign key references book(book_id),
iss_date date not null,
ret_date date
)

SQL Joining 4 tables, only selecting columns from 2

CREATE TABLE user (
userID INT AUTO_INCREMENT PRIMARY KEY,
accountTypeID INT NOT NULL,
userEmail VARCHAR(320) NOT NULL,
userPassword VARCHAR(32) NOT NULL,
userFirst VARCHAR(20) NOT NULL,
userLast VARCHAR(20) NOT NULL,
userPhone VARCHAR(10) NOT NULL,
lastAccess TIMESTAMP NOT NULL,
userRegistry DATE NOT NULL,
FOREIGN KEY (accountTypeID) REFERENCES accountType(accountTypeID));
CREATE TABLE participant (
participantID INT AUTO_INCREMENT PRIMARY KEY,
vehicleID INT NOT NULL,
userID INT NOT NULL,
eventID INT NOT NULL,
participantRegistry DATE NOT NULL,
paymentMethodID INT NOT NULL,
FOREIGN KEY (vehicleID) REFERENCES vehicle(vehicleID),
FOREIGN KEY (userID) REFERENCES user(userID),
FOREIGN KEY (eventID) REFERENCES event(eventID),
FOREIGN KEY (paymentMethodID) REFERENCES paymentMethod(paymentMethodID));
CREATE TABLE vehicle (
vehicleID INT AUTO_INCREMENT PRIMARY KEY,
makeID INT NOT NULL,
vehicleModel VARCHAR(20) NOT NULL,
vehicleYear VARCHAR(4) NOT NULL,
tshirtID INT NOT NULL,
clubID INT NOT NULL,
FOREIGN KEY (makeID) REFERENCES make(makeID),
FOREIGN KEY (tshirtID) REFERENCES tshirt(tshirtID),
FOREIGN KEY (clubID) REFERENCES club(clubID));
CREATE TABLE club (
clubID INT AUTO_INCREMENT PRIMARY KEY,
clubName VARCHAR(20) NOT NULL,
clubLogo BLOB);
$sql="SELECT U.userFirst, U.userLast, C.clubName FROM user AS U, club AS C
INNER JOIN participant AS P
on P.userID = U.userID
INNER JOIN vehicle AS V
on V.vehicleID = P.vehicleID
INNER JOIN club AS C
on C.clubID = V.clubID
ORDER BY C.clubName ASC";
We are trying to get all the clubs and all the members (first and last name) in each club.
The participant and vehicle tables are just needed to link the users table to the club table.
I know it is something simple the server we are using doesn't display sql errors and does not have phpmyadmin.
Thanks to maSTAShuFu, I came to the working result of.
SELECT U.userFirst, U.userLast, C.clubName FROM club AS C
INNER JOIN vehicle AS V
on C.clubID = V.clubID
INNER JOIN participant AS P
on V.vehicleID = P.vehicleID
INNER JOIN user AS U
on P.userID = U.userID
ORDER BY C.clubName ASC

JOIN FOUR TABLES in mysql. Error in syntax

I need to join four tables in mysql.
My database structure:
DROP DATABASE IF EXISTS db_applicant;
CREATE DATABASE db_applicant
DEFAULT CHARACTER SET 'utf8'
DEFAULT COLLATE 'utf8_unicode_ci';
USE db_applicant;
--
-- TABLE: PROFESSION
--
CREATE TABLE PROFESSION (
PROFESSION_ID INT NOT NULL AUTO_INCREMENT,
PROFESSION_NAME VARCHAR(50) NOT NULL,
PRIMARY KEY (PROFESSION_ID)
);
--
-- TABLE: SUBJECT
--
CREATE TABLE SUBJECT (
SUBJECT_ID INT NOT NULL AUTO_INCREMENT,
SUBJECT_NAME VARCHAR(50) NOT NULL,
PRIMARY KEY (SUBJECT_ID)
);
--
-- TABLE: APPLICANT
--
CREATE TABLE APPLICANT (
APPLICANT_ID INT NOT NULL AUTO_INCREMENT,
PROFESSION_ID INT NOT NULL,
LAST_NAME VARCHAR(30) NOT NULL,
FIRST_NAME VARCHAR(30) NOT NULL,
ENTRANCE_YEAR INT NOT NULL,
PRIMARY KEY (APPLICANT_ID),
FOREIGN KEY (PROFESSION_ID) REFERENCES PROFESSION (PROFESSION_ID)
);
--
-- TABLE: APPLICANT_RESULT
--
CREATE TABLE APPLICANT_RESULT (
APPLICANT_RESULT_ID INT NOT NULL AUTO_INCREMENT,
APPLICANT_ID INT NOT NULL,
SUBJECT_ID INT NOT NULL,
MARK INT,
PRIMARY KEY (APPLICANT_RESULT_ID),
FOREIGN KEY (SUBJECT_ID)
REFERENCES SUBJECT (SUBJECT_ID),
FOREIGN KEY (APPLICANT_ID)
REFERENCES APPLICANT (APPLICANT_ID)
);
--
-- TABLE: SPECIALITY_SUBJECT
--
CREATE TABLE SPECIALITY_SUBJECT (
SP_SB_ID INT NOT NULL AUTO_INCREMENT,
PROFESSION_ID INT NOT NULL,
SUBJECT_ID INT NOT NULL,
PRIMARY KEY (SP_SB_ID),
FOREIGN KEY (PROFESSION_ID)
REFERENCES PROFESSION (PROFESSION_ID),
FOREIGN KEY (PROFESSION_ID)
REFERENCES PROFESSION (PROFESSION_ID),
FOREIGN KEY (SUBJECT_ID)
REFERENCES SUBJECT (SUBJECT_ID)
);
I need that output would be something like:
first_name (this column from table applicant), last_name (this column from table applicant), entrance_year (this column from table applicant), profession_name (this column from table profession), subject_name (this column from table subject), mark (this column from table applicant_result).
You can see, that i have related fields. But i need strong INNER QUERY.
For that, i create new table with structure:
CREATE TABLE APP(
ALL_ID INT NOT NULL AUTO_INCREMENT,
APPLICANT_ID INT NOT NULL,
SUBJECT_ID INT NOT NULL,
PROFESSION_ID INT NOT NULL,
APPLICANT_RESULT_ID INT NOT NULL,
PRIMARY KEY (ALL_ID),
FOREIGN KEY (SUBJECT_ID)
REFERENCES SUBJECT (SUBJECT_ID),
FOREIGN KEY (APPLICANT_ID)
REFERENCES APPLICANT (APPLICANT_ID),
FOREIGN KEY (PROFESSION_ID)
REFERENCES PROFESSION (PROFESSION_ID),
FOREIGN KEY (APPLICANT_RESULT_ID)
REFERENCES APPLICANT_RESULT (APPLICANT_RESULT_ID)
);
And my inner:
SELECT ap.ALL_ID, a.FIRST_NAME, a.LAST_NAME,
a.ENTRANCE_YEAR, p.PROFESSION_NAME s.SUBJECT_NAME, ar.MARK
FROM app ap
JOIN (applicant a, profession p, subject s, applicant_result ar)
ON ap.APPLICANT_ID = a.APPLICANT_ID
AND ap.SUBJECT_ID = s.SUBJECT_ID
AND ap.PROFESSION_ID = p.PROFESSION_ID
AND ap.APPLICANT_RESULT_ID = ar.APPLICANT_RESULT_ID;
But i have error:
[2015-09-19 10:08:52] [42000][1064] You have an error in your SQL
syntax; check the manual that corresponds to your MySQL server version
for the right syntax to use near '.SUBJECT_NAME, ar.MARK FROM app ap
JOIN (applicant a, profession p, subject s, a' at line 1
Don't you think, a comma ',' is missing here in select statement before s.SUBJECT_NAME?
SELECT ap.ALL_ID, a.FIRST_NAME, a.LAST_NAME,
a.ENTRANCE_YEAR, p.PROFESSION_NAME s.SUBJECT_NAME, ar.MARK

sum of column returning double the value

I have the following SQL query:
SELECT s.name, s.learner_tag, s.guild_id, s.id, ifnull(sum(t.xp),0) as xp, ifnull(sum(a.ap),0) as ap, (ifnull(sum(t.xp),0)/1000+ifnull(sum(a.ap),0)/100) as level, g.name
FROM student s
INNER JOIN guild g ON g.id = s.guild_id
LEFT JOIN student_task t ON s.id = t.student_id
LEFT JOIN student_achievement a ON s.id = a.student_id
WHERE s.class_id = ".$realm_id."
GROUP BY s.name, s.learner_tag, s.guild_id, s.id, g.name
ORDER BY level DESC LIMIT 10";
However the query returns double the expected value for the ap column. There is only 1 record in the student_achievement table and the value is 25. However my query returns 50 as the value of sum(a.ap). If I edit the value, it still doubles. sum(t.xp) is working fine. Can anyone spot my mistake?
Table Structure:
CREATE TABLE student
(
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
name VARCHAR(64) NOT NULL,
guild_id INT,
class_id INT NOT NULL,
time_updated INT,
ap INT NOT NULL,
learner_tag VARCHAR(64) NOT NULL,
schoology_id INT NOT NULL,
enrollment_id INT NOT NULL,
FOREIGN KEY (guild_id) REFERENCES guild (id),
FOREIGN KEY (class_id) REFERENCES class (id)
);
CREATE TABLE student_achievement
(
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
student_id INT NOT NULL,
achievement_id INT NOT NULL,
time_added INT,
ap INT NOT NULL,
FOREIGN KEY (student_id) REFERENCES student (id),
FOREIGN KEY (achievement_id) REFERENCES achievement (id)
);
CREATE TABLE achievement
(
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
name VARCHAR(64) NOT NULL,
value INT NOT NULL,
repeatable TINYINT NOT NULL,
image_url VARCHAR(200) NOT NULL,
description VARCHAR(240) NOT NULL
);
CREATE TABLE task
(
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
name VARCHAR(64) NOT NULL,
max_xp INT,
schoology_id INT,
class_id INT NOT NULL,
processed TINYINT,
type VARCHAR(15) NOT NULL,
FOREIGN KEY (class_id) REFERENCES class (id)
);

How to link the tables mysql

I have 3 tables in my mysql database: student, progress and subject. When I try to select data:
SELECT progress.id, progress.mark, subject.pname FROM progress, subject WHERE progress.id_student = 1;
I get the following table:
id mark pname
1 5 Math
1 5 Physics
Table progress I only have one entry:
id mark id_student id_subject
1 5 1 1
How can I get student progress by student_id?
CREATE DATABASE students;
USE students;
CREATE TABLE student (
id int NOT NULL AUTO_INCREMENT,
name varchar(100) NOT NULL,
address varchar(60) NOT NULL,
byear int NOT NULL,
eyear int NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE subject (
id int NOT NULL AUTO_INCREMENT,
pname varchar(20) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE progress (
id int NOT NULL AUTO_INCREMENT,
mark int NOT NULL,
id_student int NOT NULL,
id_subject int NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (id) REFERENCES student (id),
FOREIGN KEY (id) REFERENCES subject (id)
);
SELECT progress.id, progress.mark, subject.pname
FROM progress LEFT OUTER JOIN subject ON (progress.id_subject= subject.id)
WHERE progress.id_student = 1;
Try
SELECT progress.id, progress.mark, subject.pname
FROM progress, subject
WHERE progress.id_student = 1 AND progress.id_subject = subject.id;