Derived Attribute of average of another table - mysql

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...?

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

MySQL - Update cell value using foreign key

I've got a problem creating a database.
I'd like to update children table using it's foreign key referencing to mother table automatically.
It means that when data values are inserted into the mother table, the children table gets updated on the column that is the foreign key.
Here's the code i wrote:
drop database domowa_biblioteka;
create database domowa_biblioteka;
use domowa_biblioteka;
create table pozycje
(
lp_p mediumint NOT NULL auto_increment,
nazwisko_autora char(30),
tytul char(60),
ilosc_stron int(4),
cena_oryginalna int(4),
na_sprzedaz enum('NIE','TAK'),
sprzedana enum('NIE','TAK'),
nr_pokoju mediumint,
PRIMARY KEY (lp_p)
)
;
create table kod_miedzynarodowy
(
lp_km mediumint,
ISBN char(20),
FOREIGN KEY (lp_km) REFERENCES pozycje (lp_p)
ON UPDATE CASCADE
)
;
create table pokoje
(
nr_pokoju mediumint NOT NULL auto_increment,
opis char(30),
PRIMARY KEY (nr_pokoju)
)
;
alter table pozycje ADD FOREIGN KEY (nr_pokoju) REFERENCES pokoje (nr_pokoju);
The thing is that the values of columns remain NULL after inserting data to rows.
Thanks for help!

Homework help (unitique constraint)

enter code hereI have some trouble with homework I got that I need to understand.
Ok so I have 4 tables,
1: costumer
2: order
3: orderedproduct
4. product .
They are linked by foreign key.
I need to make a unique constraint so that a costumer can only place 1 unique order per day. If the same costumer wants to order more on the same day, it has to be written on the already existing order.
TABLES:
costumer
CREATE TABLE COSTUMER (COSTUMERNR INT NOT NULL,
NAME VARCHAR(256),
CITY VARCHAR(256),
PRIMARY KEY (COSTUMERNR)) ENGINE=INNODB;
order
CREATE TABLE ORDER (ORDERNR INT NOT NULL,
ORDERDATE DATETIME,
PRIMARY KEY (ORDERNR)),
FOREIGN KEY (COSTUMERNR) REFERENCES COSTUMER(COSTUMERNR)
ON DELETE CASCADE) ENGINE=INNODB;
orderedproduct
CREATE TABLE ORDEREDPRODUCT (OPNR INT NOT NULL,
AMOUNT INT,
FOREIGN KEY (ORDERNR) REFERENCES ORDER(ORDERNR),
FOREIGN KEY (PRODUCTCODE) REFERENCES PRODUCT (PRODUCTCODE)
ON DELETE CASCADE,
CHECK (AMOUNT=>0)) ENGINE=INNODB;
product
CREATE TABLE PRODUCT (PRODUCTCODE INT NOT NULL,
NAME VARCHAR(256),
TYPE VARCHAR(256),
PRICE FLOAT,
STOCK INT,
PRIMARY KEY (PRODUCTCODE),
CHECK (AMOUNT=>0)) ENGINE=INNODB;
alter table order add unique index(orderdate, COSTUMERNR);
If you're able to split the datetime column into a date column and a time column, you can use a simple constraint:
CREATE TABLE ORDER (
ORDERNR INT NOT NULL,
ORDERDATE DATE,
ORDERTIME TIME,
...
CONSTRAINT [UniqueOrder] UNIQUE NONCLUSTERED
(
COSTUMERNR, ORDERDATE
)

Trigger in MYSQL that delete

I have posted this code in another threat, but this question is slightly different. I have to make a trigger. The question sounds like this:
"Create a trigger that removes the season if unused whenever
information about when and who produces a product is deleted (i.e.,
whenever a record is removed from the 'Produces' table, check if there
are other records about product being produced for the same season, if
not, remove also the corresponding record from the season table)"
My MYSQL code:
the MYSQL code is here:
CREATE TABLE IF NOT EXISTS Dvds(
Serial integer NOT NULL,
Name varchar(50),
Year integer,
Genre varchar(50),
Price integer,
PRIMARY KEY (Serial));
CREATE TABLE IF NOT EXISTS Shops(
Id integer NOT NULL,
Name varchar(50),
Address varchar(50),
PRIMARY KEY (Id));
CREATE TABLE IF NOT EXISTS Customers(
CNo integer NOT NULL,
AccNo integer,
Time varchar(50),
PRIMARY KEY (CNo));
CREATE TABLE IF NOT EXISTS ContactPersons(
Id integer NOT NULL,
Name varchar(50),
Phone integer,
PRIMARY KEY (Id));
CREATE TABLE IF NOT EXISTS Seasons(
StartDate date NOT NULL,
EndDate date NOT NULL,
PRIMARY KEY (StartDate,EndDate));
CREATE TABLE IF NOT EXISTS WebShops(
Id integer NOT NULL,
Url varchar(50),
FOREIGN KEY (Id) REFERENCES Shops (Id),
PRIMARY KEY (Id));
CREATE TABLE IF NOT EXISTS Producer(
Id integer NOT NULL,
Address varchar(50),
Name varchar(50),
PRIMARY KEY (Id));
CREATE TABLE IF NOT EXISTS Sold(
Id integer NOT NULL,
CNo integer NOT NULL,
Serial integer NOT NULL,
FOREIGN KEY (Id) REFERENCES Shops (Id),
FOREIGN KEY (CNo) REFERENCES Customers (CNo),
FOREIGN KEY (Serial) REFERENCES Dvds (Serial),
PRIMARY KEY (Id,CNo,Serial));
CREATE TABLE IF NOT EXISTS Has(
Id integer NOT NULL,
Serial integer NOT NULL,
FOREIGN KEY (Id) REFERENCES Shops (Id),
FOREIGN KEY (Serial) REFERENCES Dvds (Serial),
PRIMARY KEY (Id,Serial));
CREATE TABLE IF NOT EXISTS Has2(
Serial integer NOT NULL,
Producer_Id integer NOT NULL,
StartDate date NOT NULL,
EndDate date NOT NULL,
ContactPersons_Id integer NOT NULL,
FOREIGN KEY (Serial) REFERENCES Dvds (Serial),
FOREIGN KEY ( Producer_Id) REFERENCES Producer (Id),
FOREIGN KEY (StartDate) REFERENCES Seasons (StartDate),
FOREIGN KEY (EndDate) REFERENCES Seasons (EndDate),
FOREIGN KEY (ContactPersons_Id) REFERENCES ContactPersons (Id),
PRIMARY KEY (Serial,Producer_Id,StartDate,EndDate,ContactPersons_Id));
The trigger:
CREATE TRIGGER `Seasons_before_delete`
AFTER DELETE ON `Seasons`
FOR EACH ROW
BEGIN
DELETE FROM seasonstart
WHERE seasonstart.???????
DELETE FROM seasonend
WHERE seasonend.??????
END
but I really don't know. My teacher told me that I could use IF , ELSEIF, GOTOEND? But am i on the right track? I'm really blank right now what to do, so hope someone have a suggestion, what I could do to solve this?
In a trigger you have 2 virtual tables.
NEW and OLD.
Obviously in a create trigger there is no old and in a delete trigger there is no new.
So if you want to use the data of the table where the change happened (the table the trigger is attached to) you use those two tables.
Because this is a delete trigger you'll need to use the old table.
So your trigger will look something like this:
CREATE TRIGGER `Seasons_before_delete` AFTER DELETE ON `Seasons`
FOR EACH ROW
BEGIN
DELETE FROM seasonstart
WHERE seasonstart.seasonID = old.ID
DELETE FROM seasonend
WHERE seasonend.seasonID = old.ID
END
Note that it makes little sense to call a AFTER DELETE trigger "something_something_BEFORE" :-).
Further note that I have no idea why you need an IF in this trigger, the where in the delete statement already takes care of that.

How to pass references from parent table to child table in mysql database

I am new to database.
my question is that i have created a table signUp whose columns are
id, first name, last name, email and country.
and i want to create a table named accout_recharge whose columns are (email,balance)
and whenever i insert a record into signup table the newly added email in the signup table also appear in account_recharge table using references or foreign key or whatever is required but without duplication.
you can try this
CREATE TABLE signup (
id INT NOT NULL,
firstName varchar(50),
lastName varchar(50),
countryName varchar(50),
emailName varchar(50),
PRIMARY KEY (id),
index email_ind(emailName) -- updated here
) ENGINE=INNODB;
CREATE TABLE accout_recharge(
id INT,
balance DECIMAL,
email varchar(50),
FOREIGN KEY (email ) REFERENCES signup (emailName)
ON DELETE CASCADE
) ENGINE=INNODB;
MySql Foreign Key here you find more detail about foreign key reference
Update: I forget to tell you that foreign key reference always some kind of indexed column. so you need to turn you email column in an index. that why you are getting error: 150