MySQL Query - search for person who has all B - mysql

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.

Related

MySQL: How do I get to a column of another table via a mapping table

I am trying to create a database for assignments where there is a table for the tasks, a table for the persons and a table for the assignment of a person to a task.
Now I have tried to access the task table with a select statement and at the same time get all assigned persons but nothing worked. (because a task is also assigned to other tables)
Is there a way or do I have to use several statements for this?
This is how i created my Tables:
CREATE TABLE Locations (ID INT AUTO_INCREMENT, LocationID VARCHAR(255),
PRIMARY KEY (ID));
CREATE TABLE Persons (ID INT AUTO_INCREMENT, FirstName VARCHAR(255), LastName
VARCHAR(255), PRIMARY KEY (ID));
CREATE TABLE Tasks (ID INT AUTO_INCREMENT , TaskName VARCHAR(255), LocationID
INT, PRIMARY KEY (ID),
FOREIGN KEY (LocationID) REFERENCES Locations(ID));
CREATE TABLE Assinment (TaskID INT, PersonID INT,
PRIMARY KEY (TaskID, PersonID), FOREIGN KEY (TaskID)
REFERENCES Tasks(ID), FOREIGN KEY (PersonID)
REFERENCES Persons(ID));
And this is the UML.
I do not want my joins on the Assinment table like
SELECT (FirstName, LastName, TaskName) FROM ((Assinment INNER JOIN Tasks ON
Assinment.TaskID = Tasks.ID) INNER JOIN Persons ON Assinment.PersonID =
Persons.ID)
because the tasks table has more joins (e.g. locations and priorities) so i want my query start with
SELECT (ID, TaskName, FirstName, LastName, LocationName) FROM Tasks [...]
so i can get all data by id of the task
The Output then should give me this table.
Thanks for help :)
EDIT
Ouput added and desired input is now more specified
You can try subqueries :
SELECT column-names
FROM table-name1
WHERE value IN (SELECT column-name
FROM table-name2
WHERE condition)

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.

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.

Design database table to check id in another table before allowing insert

I've got what I'm sure is a really simple database question, but I don't even know what to google, so hopefully someone can help me here.
I'm trying to create 2 tables that are interconnected. For example, lets say I have an employee table with employee name and employee id, then I'm creating another table, employee_bonus, with employee id and bonus amount. What I want is for the employee_bonus table to automatically check with the employee table every time a row is inserted to make sure that the employee id exists in the employee table and reject the insert if not. The thing is, there could be multiple bonuses for a single employee, so I just want it to check that it exists, not make it one to one. Does that make sense? Is that possible? How would I do that and WHAT is that called?
Also, I'm doing this in MySql.
From wikipedia: Foreign Key
In the context of relational databases, a foreign key is a referential constraint between two tables.
http://en.wikipedia.org/wiki/Foreign_key
The following is a basic example of what you are looking for:
CREATE TABLE employees (
employee_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
family_name VARCHAR(100) NOT NULL,
first_name VARCHAR(100) NOT NULL,
birth_date DATETIME NULL DEFAULT NULL,
PRIMARY KEY(employee_id)
) ENGINE=INNODB;
CREATE TABLE employee_bonus (
bonus_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
employee_id INT UNSIGNED NOT NULL,
bonus_value DECIMAL(10,2) DEFAULT 0.00,
PRIMARY KEY(bonus_id),
KEY fk_employee_id (employee_id),
CONSTRAINT fk_employee_constraint FOREIGN KEY fk_employee_id(employee_id)
REFERENCES employees(employee_id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=INNODB;
Since it's not a 1-to-1 relationship give the employee_bonus table its own primary key and establish a foreign key relationship between the employee table's id column and the employee_id in the employee_bonus table.
If you want to avoid an error on insertion when attempting to add a missing employee, try this:
insert into employee_bonus
select ?, ?, ? -- put your insert values in here
from employee
where employee_id = ?; -- put the employee_id in here
This will insert one row if the employee exists and will do nothing if it doesn't.

Mysql foreign key

I want to make a link between a table customer and a table product by an IdProduct.
Example:
Create table customer(
idcustomer INT not null,
name Varchar(20),
idproduct INT,
);
create table Product(
idproduct INT not null,
nameProduct varchar(40)
);
How can I link the two together like the foreign key system for, when I select a customer, I can get all his products? It's a question about the structure of the database.
You want to introduce a 3rd table to resolve the many-to-many relationship between customers and products. It should consist of idcustomer and idproduct.
Then, to get all the products for a given customer:
SELECT c.name, p.nameProduct
FROM Customer c
INNER JOIN CustomerProductXref cpx
ON c.idcustomer = cpx.idcustomer
INNER JOIN product p
ON cpx.idproduct = p.idproduct
WHERE c.idcustomer = 12345
In mysql a foreign key is a special type of constraint. It is preferably created with the table, but can also be added afterwards. In this case, you might define the constraint as:
ALTER TABLE customer
ADD FOREIGN KEY (idproduct)
REFERENCES Product (idproduct);
(Note that you have to use the InnoDB engine to take advantage of FK's in mysql. More here
However FK's aren't required to make a JOIN, which is how you would link the tables in a SELECT -
select c.idcustomer, c.name, p.nameproduct
from customer c
join Product p on p.idproduct=c.idproduct;
Here's how you'd make a foreign key constraint (ignoring the cardinality issues that Joe rightly suggests):
CREATE table Product(
idproduct INT not null,
nameProduct varchar(40),
PRIMARY KEY (idproduct )
);
CREATE table customer(
idcustomer INT not null,
name Varchar(20),
idproduct INT,
FOREIGN KEY (idproduct) REFERENCES Product(idproduct )
);
Get your data like this:
SELECT * FROM Product AS P
INNER JOIN Customer AS C ON C.idproduct = P.idproduct
WHERE C.idcustomer = 1