I am trying to solve this database problems - mysql

Hi I am trying to solve the problems below I have included what I have got already. the questions are below.
This is what I have done.
CREATE TABLE casino (
casino_id int, -- a primary key
);
CREATE TABLE games (
id int,
PRIMARY KEY (id),
FOREIGN KEY (casino_id) REFERENCES casinos (id) ON DELETE CASCADE
);
CREATE TABLE countries (
id int,
PRIMARY KEY (id),
FOREIGN KEY (games_id) REFERENCES games (id) ON DELETE CASCADE
);
Question 2:
SELECT *
FROM players
LEFT JOIN games
ON players.id = games.id AND
games.type LIKE ‘%SLOT%'
ORDER BY players.id
SELECT *
FROM players LEFT OUTER JOIN players ON players.id = games.id
WHERE games.type LIKE '%SLOT%'
ORDER BY players.id ```

This is one way of making it
Type is here only char, usually type should be a table, so that a games could be many types, but that would make the query even bigger
CREATE TABLE countries (
id int,
Country_name CHAR(20),
PRIMARY KEY (id)
);
CREATE TABLE players (
id int,
ref_country_id INT,
type CHAR(50),
PRIMARY KEY (id),
FOREIGN KEY (ref_country_id) REFERENCES countries (id)
);
CREATE TABLE games (
id int,
name char(50),
type CHAR(50),
PRIMARY KEY (id)
);
CREATE TABLE rel_country_games (
ref_country_id int,
ref_games_id INT,
FOREIGN KEY (ref_country_id) REFERENCES countries (id),
FOREIGN KEY (ref_games_id) REFERENCES games (id)
);
CREATE TABLE casino (
casino_id int,
casino_name char(100),
PRIMARY KEY (casino_id)
);
CREATE TABLE rel_country_games (
ref_casino_id int,
ref_games_id INT,
FOREIGN KEY (ref_casino_id) REFERENCES casino (casino_id),
FOREIGN KEY (ref_games_id) REFERENCES games (id)
);
INSERT INTO countries VALUES(1,'Brasil'),(2,'Uruguay'),(3,'MExico')
INSERT INTO players VALUES(1,1,NULL),(2,1,'SLOT'),(3,2,'SLOT'),(4,3,'POKER')
INSERT INTO games VALUES(1,'slotgame1','SLOT'),(2,'slotgame2','SLOT'),(3,'poker','POKER');
✓
INSERT INTO rel_country_games VALUES(1,1),(1,2),(2,2),(2,3),(3,1),(3,3)
SELECT DISTINCT p.id,c.Country_name,p.type,g.type
FROM players p INNER JOIN countries c ON c.id = p.ref_country_id
INNER JOIN rel_country_games rcg ON c.id = rcg.ref_country_id
INNER JOIN games g ON rcg.ref_games_id = g.id AND g.type = p.type
WHERE p.type = 'SLOT'
ORDER BY p.id
id | Country_name | type | type
-: | :----------- | :--- | :---
2 | Brasil | SLOT | SLOT
3 | Uruguay | SLOT | SLOT
db<>fiddle here
If you have difficulties to play around with this in your mind, simply make a simple example and test your ideas.

Related

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 issue with multiple foreign

Issue:
I'm using PostgreSQL Database.
I have one table (Albums) to be linked to two other tables (Clients, Domains). So if you are Client or Domain you can have Album. But in Albums table owner can handle only single foreign key. How can I solve this issue?
Dream: Single Album can own only (1) Client or Domain. Need fix issue with foreign keys. Albums: id | owner (multiple foreign -> Clients:id or Domains:id) --> can not do this | name. I just need some smart rework.
Tables (now can have Album only Domain):
Albums
Clients
Domains
Albums (table with foreign key yet):
id | owner (foreign key -> Domains:id) | name
Clients:
id | first_name | last_name
Domains:
id | owner | name
Add 2 FK columns, and a CHECK constraint, to enforce only one of them is NOT NULL...
Something like this:
CREATE TABLE albums (
id serial PRIMARY KEY,
client_id integer,
domain_id integer,
name varchar(255) NOT NULL,
FOREIGN KEY (client_id) REFERENCES clients(id),
FOREIGN KEY (domain_id) REFERENCES domains(id),
CHECK ((client_id IS NULL) <> (domain_id IS NULL))
);
To query you can use something like this:
SELECT a.id, COALESCE(c.id, d.id) AS owner_id, COALESCE(c.name, d.name) AS owner_name,
a.name AS title
FROM albums a
LEFT JOIN clients c ON a.client_id = c.id
LEFT JOIN domains d ON a.domain_id = d.id
#e_i_pi's version
CREATE TABLE entities (
id serial PRIMARY KEY,
type integer, -- could be any other type
-- any other "common" values
);
CREATE TABLE client_entities (
id integer PRIMARY KEY, -- at INSERT this comes from table `entities`
name varchar(255) NOT NULL,
);
CREATE TABLE domain_entities (
id integer PRIMARY KEY, -- at INSERT this comes from table `entities`
name varchar(255) NOT NULL,
);
CREATE TABLE albums (
id serial PRIMARY KEY,
owner_id integer FOREIGN KEY REFERENCES entities(id), -- maybe NOT NULL?
name varchar(255) NOT NULL,
);
Query:
SELECT a.id, owner_id, COALESCE(c.name, d.name) AS owner_name, a.name AS title
FROM albums a
LEFT JOIN entities e ON a.owner_id = e.id
LEFT JOIN client_entities c ON e.id = c.id AND e.type = 1 -- depending on the type of `type`
LEFT JOIN domain_entities d ON e.id = d.id AND e.type = 2
Righto, so as suggested in the comment to the answer by #UsagiMiyamoto, there is a way to do this that allows declaration of entity types, with cascading. Note that this solution doesn't support unlimited entity types, as we need to maintain concrete FK constraints. There is a way to do this with unlimited entity types, but involves triggers and quite a bit of nastiness.
Here's the easy to understand solution:
-- Start with a test schema
DROP SCHEMA IF EXISTS "entityExample" CASCADE;
CREATE SCHEMA IF NOT EXISTS "entityExample";
SET SEARCH_PATH TO "entityExample";
-- We'll need this to enforce constraints
CREATE OR REPLACE FUNCTION is_entity_type(text, text) returns boolean as $$
SELECT TRUE WHERE $1 = $2
;
$$ language sql;
-- Unique entity types
CREATE TABLE "entityTypes" (
name TEXT NOT NULL,
CONSTRAINT "entityTypes_ukey" UNIQUE ("name")
);
-- Our client entities
CREATE TABLE clients (
id integer PRIMARY KEY,
name TEXT NOT NULL
);
-- Our domain entities
CREATE TABLE domains (
id integer PRIMARY KEY,
name TEXT NOT NULL
);
-- Our overaching entities table, which maintains FK constraints against clients and domains
CREATE TABLE entities (
id serial PRIMARY KEY,
"entityType" TEXT NOT NULL,
"clientID" INTEGER CHECK (is_entity_type("entityType", 'client')),
"domainID" INTEGER CHECK (is_entity_type("entityType", 'domain')),
CONSTRAINT "entities_entityType" FOREIGN KEY ("entityType") REFERENCES "entityTypes" (name) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT "entities_clientID" FOREIGN KEY ("clientID") REFERENCES "clients" (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT "entities_domainID" FOREIGN KEY ("domainID") REFERENCES "domains" (id) ON DELETE CASCADE ON UPDATE CASCADE
);
-- Our albums table, which now can have one owner, but of a dynam ic entity type
CREATE TABLE albums (
id serial PRIMARY KEY,
"ownerEntityID" integer,
name TEXT NOT NULL,
CONSTRAINT "albums_ownerEntityID" FOREIGN KEY ("ownerEntityID") REFERENCES "entities"("id")
);
-- Put the entity type in
INSERT INTO "entityTypes" ("name") VALUES ('client'), ('domain');
-- Enter our clients and domains
INSERT INTO clients VALUES (1, 'clientA'), (2, 'clientB');
INSERT INTO domains VALUES (50, 'domainA');
-- Make sure the clients and domains are registered as entities
INSERT INTO entities ("entityType", "clientID")
SELECT
'client',
"clients".id
FROM "clients"
ON CONFLICT DO NOTHING
;
INSERT INTO entities ("entityType", "domainID")
SELECT
'domain',
"domains".id
FROM "domains"
ON CONFLICT DO NOTHING
;
If you don't like the idea of inserting twice (once in client, once in entites, for example) you can have a trigger on inserts in the clients table, or alternately create an insert function that inserts to both tables at once.

Select from a relative with foreign key?

I have these tables:
create table CLIENTE (
idCliente int primary key auto_increment,
name varchar(255)
create table ANIMAL (
idAnimal int primary key,
name varchar(255),
foreign key (idCliente) references CLIENTE (idClinete) on delete set null on update cascade
How do I list (with Select * from methood) the names of the animals from the client John?
It's sort of an executable so I know that it wouldn't actually show the names if I runned the code, but aside that how can I just make the code?
You need to have an idCliente column in the ANIMAL table:
create table ANIMAL (
idAnimal INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255),
idCliente INT,
FOREIGN KEY (idCliente) REFERENCES CLIENTE (idCliente) ON DELETE SET NULL ON UPDATE CASCADE
);
Then you use it in a JOIN:
SELECT a.*
FROM ANIMAL AS a
JOIN CLIENTE AS c ON a.idCliente = c.idCliente
WHERE c.name = 'John';

A simple MYSQL view to disaply info about a player and its guardians

I need to create a view called phonelist which list each player, their guardians, the guardians phone number and the team they play in. How would I code this. All the information you need you should find below:
These are my tables:
CREATE TABLE Person
(
personID INT NOT NULL,
name VARCHAR(50),
address VARCHAR(70),
phone VARCHAR(15),
email VARCHAR(30),
year INT,
PRIMARY KEY (personID)
);
CREATE TABLE Player
(
personID INT NOT NULL,
dateOfBirth DATE,
school VARCHAR(30),
PRIMARY KEY (personID),
FOREIGN KEY (personID) REFERENCES Person (personID)
);
CREATE TABLE Team
(
teamID INT NOT NULL,
tName VARCHAR(70),
ageRange VARCHAR(30),
PRIMARY KEY (teamID)
);
CREATE TABLE Coach
(
personID INT NOT NULL,
dateBeganCoaching DATE,
PRIMARY KEY (personID),
FOREIGN KEY (personID) REFERENCES Person (personID)
);
CREATE TABLE coachTeam
(
personID INT NOT NULL,
teamID INT NOT NULL,
PRIMARY KEY (personID, teamID),
FOREIGN KEY (personID) REFERENCES Coach (personID),
FOREIGN KEY (teamID) REFERENCES Team (teamID)
);
CREATE TABLE playerTeam
(
personID INT NOT NULL,
teamID INT NOT NULL,
PRIMARY KEY (personID, teamID),
FOREIGN KEY (personID) REFERENCES Player (personID),
FOREIGN KEY (teamID) REFERENCES Team (teamID)
);
CREATE TABLE Guardian
(
parentID INT NOT NULL,
childID INT NOT NULL,
PRIMARY KEY (parentID, childID),
FOREIGN KEY (parentID) REFERENCES Person (personID),
FOREIGN KEY (childID) REFERENCES Person (personID)
);
CREATE TABLE Qualification
(
qualificationID INT NOT NULL,
qName VARCHAR(30),
PRIMARY KEY (qualificationID)
);
CREATE TABLE coachQualification
(
qualificationID INT NOT NULL,
personID INT NOT NULL,
PRIMARY KEY (personID, qualificationID),
FOREIGN KEY (qualificationID) REFERENCES Qualification (qualificationID),
FOREIGN KEY (personID) REFERENCES Coach (personID)
);
How would I do it so that I am using only the person table to reference the player, and guardians and how would I do it so that if a player had more than one guardian both guardian would be placed on the same line as opposed to creating an entire new row in the output to dispaly both guardian thanks.
I have tried the following but have gotten errors:
CREATE VIEW phonelist AS
SELECT Child.name, tName, Parent.name, Parent.phone
FROM playerTeam INNER JOIN Person AS Child ON playerTeam.personID = Child.personID
INNER JOIN Team ON playerTeam.teamID = Team.teamID
INNER JOIN Person AS Parent ON Guardian.parentID = Parent.personID;
Select * FROM phonelist ORDER BY name ASC;
Select P.ID, P.Name, P2.PersonID, P2.Name, P2.Phone, T2.tName as GuardianTeam T.tName as PersonTeam
INNER JOIN Player PL on PL.PErsonID=P.PersonID
INNER JOIN Guardian G on G.ParentID = P.PersonID
LEFT JOIN Person P2 on P2.PersonID = G.ChildID
INNER JOIN PlayerTeam PT on PT.PersonID = PL.PersonID
LEFT JOIN Player PL2 on PL2.PersonID = P2.PersonID
LEFT JOIN PlayerTeam PT2 on PT2.PersonID = PT2.PersonID
LEFT JOIN Team T2 on T2.TeamID = PT.TeamID
INNER JOIN Team T on T.TeamID = PT.TeamID
Ah ok edit to remove person team...
Returns all persons who are players, their guardian name, phone and guardian team as well as any players without guardians; or instances where guardians are not part of teams, or players themselves.
Select P.ID, P.Name, P2.PersonID, P2.Name, P2.Phone, T2.tName as GuardianTeam
INNER JOIN Player PL on PL.PErsonID=P.PersonID
INNER JOIN Guardian G on G.ParentID = P.PersonID
LEFT JOIN Person P2 on P2.PersonID = G.ChildID
LEFT JOIN Player PL2 on PL2.PersonID = P2.PersonID
LEFT JOIN PlayerTeam PT2 on PT2.PersonID = PT2.PersonID
LEFT JOIN Team T2 on T2.TeamID = PT.TeamID

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