sql statement not working getting errors - mysql

I am having some trouble getting a statement to run, I am looking for the total credits of each student and the student ID.
I have written:
select student.ID,sum (course.credits)
from (student natural join takes),course
where takes.course_id=course.course_id
group by student.ID
when I run this I get the following error:
column used in NATURAL join cannot have qualifier
my tables are
create table student
(ID varchar(5),
name varchar(20) not null,
dept_name varchar(20),
tot_cred numeric(3,0) check (tot_cred >= 0),
primary key (ID),
foreign key (dept_name) references department
on delete set null
create table takes
(ID varchar(5),
course_id varchar(8),
sec_id varchar(8),
semester varchar(6),
year numeric(4,0),
grade varchar(2),
primary key (ID, course_id, sec_id, semester, year),
foreign key (course_id,sec_id, semester, year) references section
on delete cascade,
foreign key (ID) references student
on delete cascade
I am not sure what the problem is. when I run this statement it works
select name, sum(course.credits)
from (student natural join takes),course
where ID=1000 and takes.course_id=course.course_id
group by name
if you can point me in the right direction I would appreciate it.. thank you

NATURAL JOIN is not recommended and can lead to subtle unintended bugs, particularly when tables are modified later. Use INNER JOIN instead:
select name, sum(c.credits)
from student s
inner join takes t
ON t.ID = s.ID
inner join course c
ON c.COURSE_ID = t.COURSE_ID
where s.ID = 1000
group by name
Best of luck.

The from clause is just wrong with regard to how you use your brackets. Just use an explicit join clause for all your joins and you should be OK:
SELECT student.ID, SUM(course.credits)
FROM student
NATURAL JOIN takes
NATURAL JOIN course
GROUP BY student.ID

Related

How to make query to show result of single recursive request?

I have the structure of the table called person,
the person has: id,first_name,last_name,mother_id,father_id
I want to build a simple query that shows data of person
like this: id,first_name,last_name,father_first_name,mother_first_name
CREATE TABLE PERSON
(
ID varchar(20),
FIRST_NAME varchar(20),
LAST_NAME varchar(20),
PHONE_NUMBER varchar(20),
BIRTH_DATE DATE,
FATHER_ID varchar(20),
MOTHER_ID varchar(20),
PRIMARY KEY (ID),
FOREIGN KEY (FATHER_ID) REFERENCES PERSON(ID),
FOREIGN KEY (MOTHER_ID) REFERENCES PERSON(ID)
);
You can query this information simply by joining the table to itself and using a table alias. Recursion is not necessary unless the hierarchy you are navigating has a varying depth. For this question there is a fixed depth and you simply wish to see the parent child relationship between 2 records. The LEFT JOIN will ensure that even if you don't have both of the parents in your database, the record will still show for that person.
SELECT
P.ID
, P.FIRST_NAME
, P.LAST_NAME
, F.FIRST_NAME FATHER_FIRST_NAME
, M.FIRST_NAME MOTHER_FIRST_NAME
FROM
PERSON P
LEFT JOIN
PERSON F ON (P.FATHER_ID = F.ID)
LEFT JOIN
PERSON M ON (P.MOTHER_ID = M.ID)

MySQL: Searching for a request using NOT EXISTS

First of all, i want to apologize for my bad english.
I have a problem on mySQL and i didn't get the right idea to solve.
I have 3 Tables:
CREATE TABLE branch (name CHAR(30), city VARCHAR(30), assets NUMERIC(16,2), PRIMARY KEY (name));
CREATE TABLE account (accountNr CHAR(9), branch CHAR(30), balance NUMERIC(12,2), PRIMARY KEY (accountNr), FOREIGN KEY (branch) REFERENCES branch(name));
CREATE TABLE customer (customerId INT(5), accountNr CHAR(9), PRIMARY KEY (customerId, accountNr), FOREIGN KEY (accountNr) REFERENCES account(accountNr));
I should find a request to find the costumerId's of the customer who have an account in all branches where city = 'New York'. I must use the 'NOT EXISTS' condition.
So i know, i have two amounts:
A. the amount of branches where the customers have an account.
B. the amount of all branches in New York
Idea: Pick all customers where B is a subset of A
you can try this query:
select distinct customerId
from customer out_customer where
( select count(account.accountNr) from account inner join branch on account.branch = branch.name
INNER join customer ON customer.accountNr = account.accountNr
where city='New York' AND out_customer.customerId = customer.customerId ) = (select count(name) from branch where city='New York')

Regarding SQL query 'join' function

I have created the following table but have troubles getting the desired output using the join function. I would like to know that if we have to select car name, price and driver name for cars made in any random year e.g.,vintage = 1995. Any help will be appreciated
create table car
(car_ID NUMBER ,
car_Name CHAR ,
car_Vintage NUMBER,
car_Price NUMBER,
PRIMARY KEY (car_ID));
create TABLE driver
(driver_ID NUMBER,
driver_Name CHAR,
PRIMARY KEY (driver_ID));
create table cardriver
(car_ID NUMBER(3) NOT NULL,
driver_ID NUMBER(4) NOT NULL,
PRIMARY KEY (car_ID,driver_ID),
FOREIGN KEY (car_ID) REFERENCES car(car_ID)
ON DELETE CASCADE,
FOREIGN KEY (driver_ID) REFERENCES driver(driver_ID)
ON DELETE CASCADE);
SELECT
c.car_Name,
c.car_Price,
d.driver_Name
FROM
cardriver as cd
INNER JOIN
car as c on c.car_ID = cd.car_ID
INNER JOIN
driver as d on d.driver_ID = cd.driver_ID
WHERE
c.car_Vintage = #Year
This assumes every car has a driver. Otherwise select from car and left join to cardriver.

SQL Getting Specific Column other than just the foreign key

I have sql table called Games as follows:
CREATE TABLE Games
(date date NOT NULL,
ho_t_id varchar(9) NOT NULL,
v_t_id varchar(9) NOT NULL,
h_score int,
v_score int,
PRIMARY KEY(date, ho_t_id, v_t_id),
FOREIGN KEY(ho_t_id) REFERENCES Team ON UPDATE CASCADE,
FOREIGN KEY(v_t_id) REFERENCES Team);
As you can see, it has two foreign keys to a table called Team. The ho_t_id and v_t_id reference to the primary key of the Team table called t_id.
I would like to show all the columns of the Games table (*) but replace the ho_t_id by the name of the team which exist in the Team table. (The Team table contains a column named Name).
How can I do that?
SELECT G.*, T1.NAME as T1_NAME, T2.NAME AS T2_NAME
FROM GAMES G
INNER JOIN TEAM T1 ON T1.T_ID=G.HO_T_ID
INNER JOIN TEAM T2 ON T2.T_ID=G.V_T_ID
You mean this?:
select t.Name, g.allOtherColumns
from Games g
inner join (
select Name, ID
from Team
) t
ON t.ID = g.v_t_id
--where ....

mysql select query from multiple tables returns duplicate results

If this question is a little vague just let me know and I will provide more info.
I have written a query that gets data from multiple tables but it isn't working how I expected it too and I am completely stumped.
Here is my code:
SELECT students.student_fname, students.student_lname
FROM students, enrolments
WHERE enrolments.courseID = 'C001';
but this just returns all of the students first and last names in the students table and these names are displayed twice.
Here is the code for the two tables:
CREATE TABLE students
(
studentID CHAR(10) NOT NULL,
student_fname VARCHAR(15) NOT NULL,
student_lname VARCHAR(15) NOT NULL,
DOB VARCHAR(10) NOT NULL,
CONSTRAINT pk_students PRIMARY KEY (studentID)
);
CREATE TABLE enrolments
(
enrolmentNo int NOT NULL AUTO_INCREMENT,
studentID CHAR(10) NOT NULL,
courseID CHAR(4) NOT NULL,
CONSTRAINT pk_enrolments PRIMARY KEY (enrolmentno),
FOREIGN KEY (studentID) REFERENCES students (studentID),
FOREIGN KEY (courseID) REFERENCES courses (courseID)
)ENGINE = INNODB;
This is because you've not defined how students relate to enrolments.
You either need to use an inner join or add a where clause that show how they relate.
For example:
FROM Students
INNER JOIN enrolments on Students.ID = enrolments.studentID
Or
FROM students, enrolements
WHERE enrolments.studentID = students.ID
The first method is newer and preferred by many; but the legacy method is also supported.
To gain a better understanding of table joins take a look at this most excellent article: http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
Otherwise you get what is called a Cartesian product of the two tables all data relates to all data.
If you do not have a unique index on enrolements (a student can only have 1 class enrolment) then a select Distinct field names or where... group by fields will also limit your results to close to what you're looking for as well.
============================ in response to follow-up comment===================
SELECT S.student_fname, S.student_lname
FROM students S
INNER JOIN enrolments E
ON S.StudentID = E.StudentID
WHERE e.courseID = 'C001'
GROUP BY S.Student_Fname, S.Student_lname
ORDER BY S.Student_LName, S.Student_FName
The group by eliminates duplicates for the same course.
The "ON statement tells the database how students relates to enrolments.
The order by is just to provide a reasonable order to results.
You cannot fetch data from two tables in this way. You have to join tables.