MySQL join multiple tables with foreign keys - mysql

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.

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)

MySQL Query returning duplicated results

Fairly new to mySQL . Trying to get a query to work, but keep getting the right results, but duplicated.
Here's the query
SELECT DISTINCT
band.band_name, concert.venue_name
FROM
band, concert
WHERE
concert.date="2012-10-17" AND band_name
IN
(SELECT band.band_name FROM band WHERE band.band_id
IN
(SELECT tour.band_id from tour where tour.tour_name
IN
(SELECT tour_name from concert where concert.date="2012-10-17")));
DDL:
CREATE TABLE band (
band_id INT,
band_name VARCHAR(50),
genre VARCHAR(20),
PRIMARY KEY (band_id) );
CREATE TABLE musician (
person_id INT,
name VARCHAR(50),
band_id INT,
PRIMARY KEY (person_id),
FOREIGN KEY (band_id) REFERENCES band(band_id) );
CREATE TABLE tour(
tour_name VARCHAR(50),
band_id INT,
PRIMARY KEY (tour_name),
FOREIGN KEY (band_id) REFERENCES band(band_id) );
CREATE TABLE venue(
venue_name VARCHAR(30),
hire_cost INT,
PRIMARY KEY (venue_name) );
CREATE TABLE concert(
concert_id INT,
date DATE,
tour_name VARCHAR(50),
venue_name VARCHAR(30),
ticket_sales INT,
PRIMARY KEY (concert_id),
FOREIGN KEY (tour_name) REFERENCES tour(tour_name),
FOREIGN KEY (venue_name) REFERENCES venue(venue_name) );
I'm totally lost. Any help would be greatly appreciated.
Joining tables is the way to go, you do not pile all your conditions into the where clause:
SELECT DISTINCT
b.band_name, c.venue_name
FROM concert c
join venue v on v.venue_name = c.venue_name -- thats how those 2 tables connect
join tour t on t.tour_name = c.tour_name -- thats how those 2 tables connect
join band b on b.band_id = t.band_id -- thats how those 2 tables connect
WHERE c.date="2012-10-17" -- and this gives you all the bandnames and
-- venuenames that play on every concert on this date
This way the DB can optimize your query and due to the joins on the tables does not need to scan so much data.

SQL How to Set Foreign Keys

I need to create 3 tables which look like this
student(sid: CHAR(12), sname: VARCHAR(50), bdate: DATE, address: VARCHAR(50), scity: VARCHAR(20), year: CHAR(20), gpa: FLOAT)
company(cid: CHAR(8), cname: VARCHAR(20))
apply(sid: CHAR(12), cid: CHAR(8))
(Bolded attributes are primary keys)
But I'm not sure how to set the foreign keys since for instance cid of apply table is both primary key in apply table and company table ( which has the same situation for sid between apply table and student table). Thanks for any help.
These are the codes for creating tables:
myQuery = "CREATE TABLE student "
+ "(sid CHAR(12), sname VARCHAR(50), "
+ "bdate DATE, address VARCHAR(50), "
+ "scity VARCHAR(20), year CHAR(20), "
+ "gpa FLOAT) ENGINE=InnoDB;";
myQuery = "CREATE TABLE company "
+ "(cid CHAR(8), cname VARCHAR(20), quota CHAR(8))ENGINE=InnoDB;";
myQuery = "CREATE TABLE apply "
+ "(sid CHAR(12), cid CHAR(8)) ENGINE=InnoDB;";
It looks like the apply table is a many-to-many join between student and company.
In that case, you'd want to set student and company like you have (though posting the output of SHOW CREATE TABLE student may get you more helpful answers). So for the apply table, you want two foreign keys: one on sid which references student.sid, and one on cid which references company.cid. Maybe something like:
ALTER TABLE apply ADD CONSTRAINT sid FOREIGN KEY (sid) REFERENCES student(sid);
ALTER TABLE apply ADD CONSTRAINT cid FOREIGN KEY (cid) REFERENCES copmany(cid);
Edit: Based on your table creation, you're not setting the primary keys either. Add a PRIMARY KEY identifier to any column you wish to be a primary key.
i the apply table set both sid and cid as foreignkeys..this table is called a junction table here the primary key is a composite primary key both sid and cid together.
appply table foreign keys are SID and CID
apply table primary key is (sid,cid) composite primary key.
Each company can have any number of students..
Each student can be part of any number of companies
but one combination wont repeat.

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

SQL Statement to write table?

working on a social networking project. just have to put together the sql statement to create the tables and need a little help with how this would be done, and how the relationships would work between the tables.
drop table users;
drop table intrest;
drop table friendships;
create table users(
id INT,
Fname char(15),
Lname char(15),
email char(20),
street char(15),
state char(2),
zip INT,
age INT,
gender char (2),
phone INT,
Password char(15),
primary key (id);
create table Instrests(
id INT,
create table friendships(
this can be done with just three tables
so far i have this done.
drop table users;
drop table intrest;
drop table friendships;
create table users(
id INT,
Fname char(15),
Lname char(15),
email char(20),
street char(15),
state char(2),
zip INT,
age INT,
gender char (2),
phone INT,
User_password char(15),
primary key (id)
foriegn key (intrest_id) references intrest(id)
);
create table Intrests(
id INT,
description char(30),
Primary key (id),
foreign key (users_id) references users(id)
);
create table User_intrest(
foreign key (user_id) references user(id),
foreign key (intrest_id) references intrest(id)
);
create friendships(
User_1_id INT,
User_2_id INT,
status Char(20),
foreign key (user_id) references user(id)
);
It looks like you're asking how to create the Interests and Friendships tables? And how they relate?
First, you'll need to spell Interests the same in the drop and create statement. You're right that Interests will link back to the Users by the ID. You'll probably want both an Interests Table, with an InterestID and description, and a linking table, with both the UserID and InterestID. Otherwise, you'll have lots of duplicate interests listed, one for each user.
The friendships table may be just a linking table, linking two userIDs together.
Try to imagine the data you need, and create the tables based on that:
User - 1, name - Joe, other info...
User - 2, name - Kris, other info..
User - 3, name - Lee, other info...
Interest - 1, name - reading
Interest - 2, name - parasailing
Interest - 3, name - skimboarding
UserInterest - User 1, Interest 2
UserInterest - User 1, Interest 3
UserInterest - User 2, Interest 2
Friendship - User 1, User 2
That tells you that Joe and Kris are friends and they both like parasailing, although Joe also likes skimboarding.
This doesn't tell you how to create the tables, but perhaps it will point you in the right direction. If this is a homework assignment, and it looks like it, you still want to do the work yourself.
You will need a an intermediate table between Users and Interests if you plan on having a many to many relationship between the two tables.
Also for Friendship, I would recomend a intermediate table between Friendship and Users as well, with that table having a link to a "Friendship Type" table to identify the friendship/relationship.
And if ThursdayGeek is correct and this is a homework assignment then I will stop here with my suggestions because there is more to the intermediate tables that you need to learn about before you implement them.
drop table users;
drop table intrest;
drop table friendships;
create table users(
id INT,
Fname char(15),
Lname char(15),
email char(20),
street char(15),
state char(2),
zip INT,
age INT,
gender char (2),
phone INT,
User_password char(15),
primary key (id)
foriegn key (intrest_id) references intrest(id)
);
create table Intrests(
id INT,
description char(30),
Primary key (id),
foreign key (users_id) references users(id)
);
create table User_intrest(
foreign key (user_id) references user(id),
foreign key (intrest_id) references intrest(id)
);
create friendships(
User_1_id INT,
User_2_id INT,
status Char(20),
foreign key (user_id) references user(id)
);
sorry not really good at this, anyways, this is what I have done for the sql statements so far.