MySql Matching id defined data with data from different rows - mysql

I'm taking Database Management course this semester and I'm working on one of assigned problems we got. We are supposed to create a database and give mysql statements for actions described.
The action that issues me is described like this:
Get the numbers of students who have the same sex and live in the same town as student 20.
I tried using inner join but I got errors which confuse me. I also tried matching but since there is no data stated, that didn't work either.
Here is my code.
create table student (nr INTEGER PRIMARY KEY, town TEXT, birthdate
INTEGER, sex INTEGER, sname TEXT, ssurname TEXT);
create table lecturer (lnr INTEGER PRIMARY KEY, lname TEXT, lsurname TEXT);
create table course (cnr INTEGER PRIMARY KEY, cname TEXT, lnr INTEGER,
FOREIGN KEY fk_clnr (lnr)
REFERENCES lecturer (lnr) );
create table enrolledin (nr INTEGER, cnr INTEGER,
FOREIGN KEY fk_nr (nr)
REFERENCES student (nr),
FOREIGN KEY fk_cnr (cnr)
REFERENCES course (cnr) );
create table exam (lnr INTEGER, cnr INTEGER, nr INTEGER, note TEXT,
FOREIGN KEY fk_enr (nr)
REFERENCES student (nr),
FOREIGN KEY fk_ecnr (cnr)
REFERENCES course (cnr),
FOREIGN KEY fk_elnr (lnr)
REFERENCES lecturer (lnr) );
select nr, sex, town
FROM student
WHERE student AS S INNER JOIN matches M ON
S.sex = M.sex AND S.town = M.town WHEN nr = 20;

Get the numbers of students who have the same sex and live in the same town as student 20
You should resolve this by a subselect. I dont understand why you use a join. All information are in student aviable.
So lets start:
First you need sex of student with nr 20:
SELECT sex FROM student WHERE nr = 20;
Than you need town of student with nr 20:
SELECT town FROM student WHERE nr = 20;
Now you need the count of students:
SELECT COUNT(*) FROM student;
At least you put everything together:
SELECT COUNT(*) FROM student
WHERE sex = (
SELECT sex FROM student WHERE nr = 20
)
AND town LIKE (
SELECT town FROM student WHERE nr = 20
);

Related

MySQL Query - search for person who has all B

I am trying to solve an SQL question about below question in MySQL
output the patient name who has taken treatment from all doctors at least once.
I am stuck with the "all doctors".
Is there a way to get this result with one query?
Where I have the table,
CREATE table patient (
pno VARCHAR(5) PRIMARY KEY,
name VARCHAR(15) NOT NULL,
);
CREATE table doctor (
dno VARCHAR(5) PRIMARY KEY,
name VARCHAR(15) NOT NULL,
);
CREATE table record (
id INT auto_increment PRIMARY KEY,
dno VARCHAR(5),
pno VARCHAR(5),
FOREIGN KEY(dno) REFERENCES doctor(dno)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY(pno) REFERENCES patient(pno)
ON UPDATE CASCADE
ON DELETE CASCADE
);
pno is the patient number, which is referenced by record,
dno is the doctor's number, which is referenced by record.
I think IN and EXSISTS doen't work in this situation.
Maybe using count(*) would work but, I tried using subquery below, and couldn't solve this.
SELECT count(*)
FROM doctor;
You can:
first select the cardinality of the doctors,
then select all patients whose distinct count of doctors is equal to the cardinality of doctors
hence get the patients' names.
The query should look like this:
SELECT p.name
FROM patient p
WHERE p.pno IN (
SELECT r.pno
FROM record r
GROUP BY r.pno
HAVING COUNT(DISTINCT r.dno) = (
SELECT COUNT(*)
FROM doctors
)
)
Note: I'll leave an SQL fiddle link here in case of question update with some sample data.

MySQL join multiple tables with foreign keys

I stored my address information in several tables: country, zip, street and number.
CREATE TABLE country (
country_id INT,
name VARCHAR(45),
PRIMARY KEY(country_id));
CREATE TABLE zip (
zip_id INT,
zip VARCHAR(45),
PRIMARY KEY(zip_id));
CREATE TABLE street (
street_id INT,
name VARCHAR(45),
PRIMARY KEY(street_id));
CREATE TABLE number (
number_id INT,
number INT,
PRIMARY KEY(number_id));
I put the information together using an address table which contains the ids of the previously mentioned tables as foreign keys.
CREATE TABLE address (
address_id INT,
country_id INT,
zip_id INT,
street_id INT,
number_id INT,
PRIMARY KEY(address_id),
FOREIGN KEY(country_id) REFERENCES country(country_id),
FOREIGN KEY(zip_id) REFERENCES zip(zip_id),
FOREIGN KEY(street_id) REFERENCES street(street_id),
FOREIGN KEY(number_id) REFERENCES number(number_id));
How can I display a complete address with one SQL statement?
As mentioned in the comments first you need to add the id's from the other tables into the adress table. In the sql above you set the relation with foreign keys but the address table don't have any fields to map it to. You should create the address table like:
CREATE TABLE address (
address_id INT,
country_id INT,
zip_id INT,
street_id INT,
number_id INT,
PRIMARY KEY(address_id),
FOREIGN KEY(country_id) REFERENCES country(country_id),
FOREIGN KEY(zip_id) REFERENCES zip(zip_id),
FOREIGN KEY(street_id) REFERENCES street(street_id),
FOREIGN KEY(number_id) REFERENCES number(number_id));
Then you can make a join like:
SELECT a.address_id, c.name, s.name, n.number, z.zip
FROM address a
JOIN country c ON c.country_id = a.country_id
JOIN street s ON s.street_id = a.street_id
JOIN number n ON n.number_id = a.number_id
JOIN zip z ON z.zip_id = a.zip_id
But making a table for number (if you mean street number?) and zip might not be the best idea. Normally you want a table for countries but having a table for each zip instead of just adding them directly to the address table seems wrong. But I don't have all the info so you might have a good reason for it.

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)

Basic MySQL project: defining keys and on delete cascades

I am a beginning student in MYSQL and I have the following assignment:
Create a database with the name UNIVERSITY. Then create tables in UNIVERSITY according to the following schemas:
Student(Sid; Sname;GPA)
MajorsIn(Sid;Major)
Book(BookNo; Title; Price)
Cites(BookNo;CitedBookNo)
Buys(Sid;BookNo)
A student can have multiple Majors or no major. A tuple (b,c) in the relation
Cites indicates that the book with book number b cites the book with book number c.
Where appropriate, add “ON DELETE CASCADE” statements with the foreign key
constraints.
Here is the code I have so far:
CREATE DATABASE University;
CREATE TABLE Stu ( sid INTEGER,
gpa REAL,
PRIMARY KEY (sid) )
CREATE TABLE Majorsin ( sid INTEGER,
Major CHAR(10),
PRIMARY KEY (sid) )
CREATE TABLE Book ( bookno INTEGER,
title CHAR(10),
price REAL,
CREATE TABLE Cites ( bookno INTEGER,
citedbookno INTEGER,
CREATE TABLE Buys ( sid INTEGER,
bookno INTEGER,
PRIMARY KEY (sid) )
My question is: what changes to the above code do I need to make to meet the requirements? In particular, what changes do I need to make in terms of defining the keys and where do i need to put "ON DELETE CASCADES?'
Sorry if this is a basic/general question: I'm a noob and could use some help getting through this first assignment.
Thanks!

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')