MySQL Query returning duplicated results - mysql

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.

Related

Why are my sql foreign key values == null?

Im new to sql, I wrote these create table statements and inserted data into them. in the coffee table shop_id and supplier_id are foreign keys for tables I have already inserted data into. When I do my select statement these two values are null. why is this?
shop_id and supplier_id are null
# CREATE TABLES
CREATE TABLE COFFEE_SHOP (
shop_id int NOT NULL ,
shop_name varchar(50),
city varchar(50),
state CHAR (2),
PRIMARY KEY (shop_id)
);
CREATE TABLE SUPPLIER (
supplier_id int NOT NULL ,
company_name varchar(50),
country varchar(30),
sales_contact_name varchar (50),
email varchar(50) NOT NULL,
PRIMARY KEY (supplier_id)
);
CREATE TABLE COFFEE (
coffee_id int NOT NULL ,
shop_id int,
supplier_id int,
coffee_name VARCHAR (30),
price_per_pound numeric(5,2),
PRIMARY KEY (coffee_id),
FOREIGN KEY (shop_id) REFERENCES COFFEE_SHOP(shop_id),
FOREIGN KEY (supplier_id) REFERENCES SUPPLIER(supplier_id)
);
CREATE TABLE EMPLOYEE (
employee_id int NOT NULL ,
FirstName varchar(30),
LastName varchar(30),
hire_date date,
job_title varchar(30),
shop_id int,
PRIMARY KEY(employee_id),
FOREIGN KEY (shop_id) REFERENCES COFFEE_SHOP(shop_id)
);
# INSERTION QUERIES
INSERT INTO COFFEE_SHOP (shop_id, shop_name, city,state)
VALUES ('45', 'Stavanger', 'Norway','fl');
INSERT INTO SUPPLIER (supplier_id, company_name, country,sales_contact_name,email)
VALUES ('25', 'lovanger', 'Forway','Tl','sql#gmail.com');
INSERT INTO COFFEE (coffee_id,coffee_name,price_per_pound )
VALUES ('15','espresso','15');
SELECT *
FROM COFFEE
Hey you are missing the concept of Foreign Key.
It is never for Foreign key to have the values directly from another table when you have defined Foreign key in first table.
what it simply means that you are tying two tables in order to make sure that no data is inserted in another table which doesn't have a reference key in first table.
To make it easier for you to understand, lets take your coffee table example.
Let's suppose you are trying to insert a row in Coffee table with a supplier Id which is not present in Supplier Table.
INSERT INTO COFFEE (coffee_id,coffee_name,price_per_pound,supplier_id )
VALUES ('15','espresso','15','111');
This will error out as
Schema Error: Error: ER_NO_REFERENCED_ROW_2: Cannot add or update a child row: a foreign key
constraint fails (`test`.`COFFEE`, CONSTRAINT `COFFEE_ibfk_2` FOREIGN KEY
(`supplier_id`) REFERENCES `SUPPLIER` (`supplier_id`))
Which means you can't insert any row in coffee table with Supplier Id which is not already present in Supplier table.
That's the whole fundamental of Foreign Key and it's use.
So that no corrupt data is inserted in tables.
This foreign key establishes referential integrity between Supplier and Coffee tables, thus, restricting the insertion of a new row when the SupplierId value of the inserted row does not match the ID column values of the Supplier's table.
Let me know if you have any further doubt
Simply because you don't insert shop_id and supplier_id values to the table, you should also insert these values as well.
Here:
INSERT INTO COFFEE (coffee_id,coffee_name,price_per_pound,shop_id,supplier_id)
VALUES ('15','espresso','15','45','25');

Derived Attribute of average of another table

Is there a way to create a column in a table that derives its values from the average of the values of a column of another table.
I'd like to have the rating column in the table Series have the averages of the opinion column of the table Status where the name are the same.
This is the current database.
CREATE TABLE User
(UName VARCHAR(30),
Password VARCHAR(30) NOT NULL,
Score INT,
PRIMARY KEY(UName));```
CREATE TABLE Status
(UName VARCHAR(30),
SName VARCHAR(50),
Opinion INT,
CONSTRAINT OpinionCk CHECK (Opinion BETWEEN 0 AND 100),
PRIMARY KEY(UName, Sname),
FOREIGN KEY(UName) REFERENCES User(UName) ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (SName) REFERENCES Serie(SName) ON UPDATE CASCADE ON DELETE CASCADE);
/* here comes the part where i have the problem:*/
CREATE TABLE Series
(SName VARCHAR(50),
Rating REAL AS (
(SELECT AVG(Opinion)
FROM Status
WHERE
Status.SName = Series.SName)
),
Genre VARCHAR(50),
Episodecount INT,
PRIMARY KEY(SName));
Is there a better way to create the table Series? Maybe as a view...?

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.

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)

querying primary keys from a foreign key

I'm fairly new to MySQL and I am struggling querying or referencing primary key's by foreign keys specified in a table. Can someone please explain how to do this in fairly simple terms, as everything I've searched is a bit hard to understand considering majority of others have allot more MySQL knowledge then me.
Let's just assume these are the tables:
CREATE TABLE IF NOT EXISTS customer(
custID int AUTO_INCREMENT,
custLname varchar(30),
custAdd varchar(100),
custSuburb varchar(30),
custPcode varchar(4),
custState varChar(20),
custPhone varchar(10),
PRIMARY KEY (custID)
)ENGINE = INNODB;
CREATE TABLE IF NOT EXISTS tour(
DailyTourID int,
tourDate DATE,
tourTime TIME,
tourName varchar(30),
tourDriverID int,
tourBusID varchar(2),
PRIMARY KEY (DailyTourID, tourDate),
) ENGINE = INNODB;
CREATE TABLE IF NOT EXISTS TourCustLink(
TourCustLinkID int AUTO_INCREMENT,
TourID int,
TourDate DATE,
customerID int,
PRIMARY KEY (TourCustLinkID),
FOREIGN KEY (TourID, TourDate) REFERENCES tour(DailyTourID, tourDate),
FOREIGN KEY (customerID) REFERENCES customer(custID)
) ENGINE = INNODB;
I am aware this is a pretty bad example, but lets say I want to show the custLname, custAdd, custPhone and tourDates for each customer. How would I accomplish this?
JOIN them:
SELECT
c.custLname,
c.custAdd,
c.custPhone,
t.TourDate,
t.TourName,
...
FROM TourCustLink AS tl
INNER JOIN Customer AS c ON tl.customerId = c.custID
INNER JOIN Tour AS t ON tl.tourID = t.DailyTourID
AND tl.tourDate = t.tourDate;
You might also need to use OUTER JOINs (LEFT JOIN or RIGHT JOIN) instead of INNER JOIN, in case you want to include those unmatched rows.
For more information about the JOIN types see this article:
A Visual Explanation of SQL Joins