MYSQL Select One Row With Less - mysql

I'm making a database for a unit and I need a query that selects the vet with less appointments assigned so I can assign the next appointment to him or her. I don't know how to start, but I'm pretty sure I'll have to use variables here. Those are my tables:
CREATE TABLE IF NOT EXISTS staff (
stafId MEDIUMINT UNSIGNED AUTO_INCREMENT,
stafAdd VARCHAR(150) NOT NULL,
stafConNum VARCHAR(15) NOT NULL,
stafEma VARCHAR(40) NOT NULL,
stafFirNam VARCHAR(20) NOT NULL,
stafLasNam VARCHAR(30) NOT NULL,
stafPos ENUM('nurse', 'vet') NOT NULL,
PRIMARY KEY (stafId)
) engine = InnoDB;
CREATE TABLE IF NOT EXISTS vet (
vetId MEDIUMINT UNSIGNED AUTO_INCREMENT,
FOREIGN KEY (vetId) REFERENCES staff(stafId),
PRIMARY KEY (vetId)
) engine = InnoDB;
CREATE TABLE IF NOT EXISTS appointment (
appoId MEDIUMINT UNSIGNED AUTO_INCREMENT,
appoDat DATETIME NOT NULL,
appoPetId MEDIUMINT UNSIGNED,
FOREIGN KEY (appoPetId) REFERENCES pet(petId),
appoVetId MEDIUMINT UNSIGNED,
FOREIGN KEY (appoVetId) REFERENCES vet(vetId),
PRIMARY KEY (appoId)
) engine = InnoDB;

You should start by looking up the mysql MIN() function. Follow that up with learning about JOINs and you'll be breezing through this.

You could get the vet's with the number of appointment like this:
SELECT
*
FROM
(
SELECT
vet.vetId,
COUNT(*) AS nbrOfAppointment
FROM
vet
JOIN appointment
ON vet.vetId = appointment.appoVetId
) AS tbl
ORDER BY tbl.nbrOfAppointment ASC

This Request gives you the number of appointement per vet ordered by number of appointement.
Select vet.id, count(*) as nb_appointement
from vet
inner join appointement app on vet.vetId = app.appoVetId
group by vet.id
order by nb_appointement asc

Related

Didnt display results in database

I have a little problem with one database. I have already entered data in the individual tables in the database. The problem is that with this code, it displays the column names, but didnt return rows. I can't find the error. I think the problem is in JOIN itself. Any ideas for solving the problem?
SELECT cars.brand,
cars.model,
cars.yearofproduction,
cars.engine_type,
parts.part_name,
parts.price AS MONEY,
parts.quantity
FROM CATALOG
JOIN parts
ON parts.part_name = parts.id
JOIN cars
ON CATALOG.car_id = cars.id
WHERE quantity >= '0'
HAVING MONEY < (
SELECT AVG(price)
FROM cars
);
And here the tables. I've already insert values in the tables.
CREATE TABLE CATALOG.parts
(
id INT AUTO_INCREMENT PRIMARY KEY,
part_name VARCHAR(255) NOT NULL,
price DECIMAL NOT NULL,
DESCRIPTION VARCHAR(255) DEFAULT NULL,
quantity TINYINT DEFAULT 0
);
CREATE TABLE CATALOG.cars
(
id INT AUTO_INCREMENT PRIMARY KEY,
brand VARCHAR(255) NOT NULL,
model VARCHAR(255) NOT NULL,
yearofproduction YEAR NOT NULL,
engine_type SET('Diesel', 'A95', 'Gas', 'Metan')
);
CREATE TABLE CATALOG.catalog
(
part_id INT NOT NULL,
CONSTRAINT FOREIGN KEY(part_id) REFERENCES parts(id)
ON DELETE RESTRICT ON UPDATE CASCADE,
car_id INT NOT NULL,
CONSTRAINT FOREIGN KEY(car_id) REFERENCES cars(id)
ON DELETE RESTRICT ON UPDATE CASCADE,
PRIMARY KEY(part_id, car_id)
);

Can I improve my movie selecting SQL query

I've created a database to store movies data. My tables are the following:
movies:
CREATE TABLE IF NOT EXISTS `movies` (
`movieId` int(11) NOT NULL AUTO_INCREMENT,
`imdbId` varchar(255) DEFAULT NULL,
`imdbRating` float DEFAULT NULL,
`movieTitle` varchar(255) NOT NULL,
`movieLength` varchar(255) NOT NULL,
`imdbRatingCount` varchar(255) NOT NULL,
`poster` varchar(255) NOT NULL,
`year` varchar(255) NOT NULL,
PRIMARY KEY (`movieId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
I have a table in which i store movie actors:
CREATE TABLE IF NOT EXISTS `actors` (
`actorId` int(10) NOT NULL AUTO_INCREMENT,
`actorName` varchar(255) NOT NULL,
PRIMARY KEY (`actorId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
And one other in which i store the relation between the movies and actors: (movieActor)
CREATE TABLE IF NOT EXISTS `movieActor` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`movieId` int(10) NOT NULL,
`actorId` int(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Now when i want to select a list of movies in which are the selected actors my query is:
SELECT *
FROM movies m inner join
(SELECT movieId FROM movieActor WHERE actorId IN(1,2,3) GROUP BY movieId having count(*) = 3) ma ON m.movieId = ma.movieId
WHERE imdbRating IS NOT NULL ORDER BY imdbRating DESC
This is working perfectly, but i don't know that this is the optimal table structure and query to accomplish this. Are there any better table structure to store data or query the list?
First of all, use indexes on your tables. In my opinion it should be useful to have 3 indexes on movieActor. MovieId - ActorID - MovieIdActorId.
Second try tu use foreign keys. These help to identify the best execution plan for your dbs.
Third try to avoid generating temp tables in your execution plan of your query. Subselects often creates temp tables which are used when the database has to temporarily save something in the RAM. To check this, write EXPLAIN in front of goer query.
I would write it like this:
SELECT m.*, movieActor
FROM movies m inner join
movieActor ma ON m.movieId = ma.movieId
WHERE imdbRating IS NOT NULL
and actorId IN(1,2,3)
GROUP BY movieId
having count(*) = 3)
ORDER BY imdbRating DESC
(Not tested)
Just try to optimize it with the EXPLAIN keyword. It also can help you to create the right indexes.

Join table on already joined table

I'm struggling to put together a select statement that joins 3 tables.
Here's the database:
CREATE TABLE Beerstyles
(
style_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
style_name VARCHAR(50) NOT NULL
)ENGINE=InnoDB;
CREATE TABLE Breweries
(
brew_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
booth_num VARCHAR(10) NOT NULL,
brew_name VARCHAR(50) NOT NULL
)ENGINE=InnoDB;
CREATE TABLE Beers
(
beer_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
beer_name VARCHAR(50) NOT NULL,
alc_vol DECIMAL(2,1) NOT NULL,
fk_style_id INT NOT NULL,
fk_brew_id INT NOT NULL
)ENGINE=InnoDB;
CREATE TABLE Favorites
(
fav_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
user_id VARCHAR(55) NOT NULL,
fk_beer_id INT NOT NULL,
fav_comment VARCHAR(255)
)ENGINE=InnoDB;
ALTER TABLE Beers ADD CONSTRAINT FK_BeerStyle_Style FOREIGN KEY (fk_style_id) REFERENCES Beerstyles (style_id);
ALTER TABLE Beers ADD CONSTRAINT FK_BeerBrew_Brew FOREIGN KEY (fk_brew_id) REFERENCES Breweries (brew_id);
ALTER TABLE Favorites ADD CONSTRAINT FK_FavBeer_Beer FOREIGN KEY (fk_beer_id) REFERENCES Beers (beer_id);
And here's the first part:
SELECT * FROM Favorites JOIN Beers ON Favorites.fk_beer_id = Beers.beer_id
I need to mix in the brew_name, but haven't been able to get it right. When I try to join Breweries (ON Favorites.fk_brew_id = Breweries.brew_id) i get an error saying "Unknown column 'Favorites.fk_brew_id' in 'on clause'"
Hope you guys can help me out :)
There is no fk_brew_id in the Favorite table, but you have to add the JOIN condition to the Beers table not to the Favorite table like this:
SELECT
bw.brew_name,
b.beer_name,
f.fav_comment,
...
FROM Favorites AS f
INNER JOIN Beers AS b ON f.fk_beer_id = b.beer_id
INNER JOIN Breweries AS bw ON b.fk_brew_id = bw.brew_id;
SELECT *
FROM Favorites
JOIN Beers
ON Favorites.fk_beer_id = Beers.beer_id
JOIN Breweries
ON Beers.fk_brew_id = Breweries.brew_id
Of course is real life you shoudl never use select *. When you have a join you are repeating columns and causing your query to be slower.

What's wrong with this SELECT Statement?

I'm getting this error:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near '' JOIN `shirts_link` ON `shirts_link`.`shirt_id`=`shirts`.`id`
JOIN `shirt_sizes' at line 1
I've been combing over it for nearly a half an hour now and can't figure it out. Can someone please point it out to me? Here's the code.
SELECT
`shirts`.`shirt_name`,
`shirts`.`men` AS `main_photo`,
GROUP_CONCAT ( `shirt_sizes`.`size_name` ) AS `sizes`
FROM
`shirts`
JOIN
`shirts_link` ON `shirts_link`.`shirt_id`=`shirts`.`id`
JOIN
`shirt_sizes` ON `shirt_sizes`.`id`=`shirts_link`.`size_id`
JOIN
`shirt_prices` ON `shirt_prices`.`id`=`shirts_link`.`price_id`
WHERE `men`!=''
GROUP BY
`shirt_prices`.`price_cat`
In case the problem goes deeper than this script, here's the other tables I'm trying to tie together.
Shirts Table
CREATE TABLE shirts (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
shirt_name VARCHAR(20) NOT NULL,
men VARCHAR(10) NULL,
women VARCHAR(10) NULL,
boys VARCHAR(10) NULL,
girls VARCHAR(10) NULL,
babies VARCHAR(10) NULL,
)ENGINE=INNODB;
INSERT INTO shirts(shirt_name,men,women,boys,girls,babies) VALUES
('Crewneck Tee','me_crn','wo_crn','bo_crn','gi_crn','ba_crn'),
('V-Neck Tee','me_vnc','wo_vnc','','',''),
('Scoop Neck Tee','','wo_sco','','',''),
('Raglan Tee','me_rag','wo_rag','bo_rag','gi_rag',''),
('Ringer Tee','me_rin','wo_rin','bo_rin','gi_rin',''),
('Cap Sleeve Tee','','wo_cap','','gi_cap',''),
('Tank Top','me_tan','wo_tan','bo_tan','gi_tan',''),
('Spaghetti Strap','','wo_spa','','',''),
('Hoodie','me_hod','wo_hod','bo_hod','gi_hod','ba_hod'),
('Onsie','','','','','ba_ons');
Size Table
CREATE TABLE shirt_sizes (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
size_name VARCHAR(10) NOT NULL
)ENGINE=INNODB;
INSERT INTO shirt_sizes(size_name) VALUES
('new born'),
('6 months'),
('12 months'),
('18 months'),
('2T'),
('3T'),
('4T'),
('5T'),
('x-small'),
('small'),
('medium'),
('large'),
('1x-large'),
('2x-large'),
('3x-large'),
('4x-large'),
('5x-large');
Price Table
CREATE TABLE shirt_prices (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
price_cat VARCHAR(10) NOT NULL,
price NUMERIC(6,2) NOT NULL
)ENGINE=INNODB;
INSERT INTO shirt_prices(price_cat,price) VALUES
('crn_01','25.40'),('crn_02','26.30'),('crn_03','27.20'),('crn_04','28.10'),
('crn_05','29.11'),
('vnc_01','26.21'),('vnc_02','27.11'),('vnc_03','28.01'),('vnc_04','29.02'),
('vnc_05','30.80'),
('sco_01','28.10'),
('rag_01','29.22'),('rag_02','30.44'),('rag_03','31.70'),('rin_01','29.22'),
('rin_02','30.44'),('rin_03','31.70'),
('cap_01','29.04'),('cap_02','30.26'),
('tan_01','25.31'),('tan_02','26.21'),
('spa_01','26.30'),('spa_02','27.11'),
('hod_01','35.21'),('hod_02','36.11'),('hod_03','37.10'),('hod_04','38.11');
Shirt Link Table
CREATE TABLE shirts_link (
adult VARCHAR(1) NOT NULL,
kids VARCHAR(1) NOT NULL,
babies VARCHAR(1) NOT NULL,
shirt_id INT UNSIGNED NOT NULL,
size_id INT UNSIGNED NOT NULL,
price_id INT UNSIGNED NOT NULL,
PRIMARY KEY (shirt_id,size_id,price_id),
FOREIGN KEY (`shirt_id`) REFERENCES `shirts`(`id`),
FOREIGN KEY (`size_id`) REFERENCES shirt_sizes(`id`),
FOREIGN KEY (`price_id`) REFERENCES shirt_prices(`id`)
)ENGINE=INNODB;
INSERT INTO shirts_link (adult, kids, babies, shirt_id, size_id, price_id) VALUES
('n','n','y','1','1','1'),('n','n','y','1','2','1'),('n','n','y','1','3','1'),('n','n','y','1','4','1'),
('n','n','y','1','5','1'),('n','n','y','1','6','1'),('n','n','y','1','7','1'),('n','n','y','1','8','1'),
('n','y','n','1','9','1'),('y','y','n','1','10','1'),('y','y','n','1','11','1'),('y','y','n','1','12','1'),
('y','y','n','1','13','1'),('y','n','n','1','14','2'),('y','n','n','1','15','3'),('y','n','n','1','16','4'),
('y','n','n','1','17','5'),
('y','n','n','2','10','6'),('y','n','n','2','11','6'),('y','n','n','2','12','6'),('y','n','n','2','13','6'),
('y','n','n','2','14','7'),('y','n','n','2','15','8'),('y','n','n','2','16','9'),('y','n','n','2','17','10'),
('y','n','n','3','10','11'),('y','n','n','3','11','11'),('y','n','n','3','12','11'),('y','n','n','3','13','11'),
('y','n','n','3','14','11'),
('y','y','n','4','10','12'),('y','y','n','4','11','12'),('y','y','n','4','12','12'),('y','y','n','4','13','12'),
('y','n','n','4','14','13'),('y','n','n','4','15','14'),
('y','y','n','5','10','15'),('y','y','n','5','11','15'),('y','y','n','5','12','15'),('y','y','n','5','13','15'),
('y','n','n','5','14','16'),('y','n','y','5','15','17'),
('y','y','n','6','10','18'),('y','y','n','6','11','18'),('y','y','n','6','12','18'),('y','y','n','6','13','18'),
('y','n','n','6','14','19'),
('y','y','n','7','10','20'),('y','y','n','7','11','20'),('y','y','n','7','12','20'),('y','y','n','7','13','20'),
('y','n','n','7','14','21'),
('y','n','n','8','10','22'),('y','n','n','8','11','22'),('y','n','n','8','12','22'),('y','n','n','8','13','22'),
('y','n','n','8','14','23'),
('n','n','y','9','5','24'),('n','n','y','9','6','24'),('n','n','y','9','7','24'),('n','n','y','9','8','24'),
('n','n','y','9','9','24'),('y','y','n','9','10','24'),('y','y','n','9','11','24'),('y','y','n','9','12','24'),
('y','y','n','9','13','24'),('y','y','n','9','14','25'),('y','n','n','9','15','26'),('y','n','n','9','16','27'),
('y','n','n','9','16','25'),
('n','n','y','10','1','1'),('n','n','y','10','2','1'),('n','n','y','10','3','1'),('n','n','y','10','4','1');
Where clause belongs after the entire from clause, meaning after all the joins.
You have this WHERE clause in the wrong place:
WHERE `men`!=''
Move it in front of your GROUP BY clause.
UPDATE: Here is a reformatted version of your query:
SELECT `shirts`.`shirt_name`
, `shirts`.`men` AS `main_photo`
, GROUP_CONCAT ( `shirt_sizes`.`size_name` ) AS `sizes`
FROM `shirts`
JOIN `shirts_link`
ON `shirts_link`.`shirt_id`=`shirts`.`id`
JOIN `shirt_sizes`
ON `shirt_sizes`.`id`=`shirts_link`.`size_id`
JOIN `shirt_prices`
ON `shirt_prices`.`id`=`shirts_link`.`price_id'
WHERE `men` != ''
GROUP BY `shirt_prices`.`price_cat`

How to create relationships in MySQL

In class, we are all 'studying' databases, and everyone is using Access. Bored with this, I am trying to do what the rest of the class is doing, but with raw SQL commands with MySQL instead of using Access.
I have managed to create databases and tables, but now how do I make a relationship between two tables?
If I have my two tables like this:
CREATE TABLE accounts(
account_id INT NOT NULL AUTO_INCREMENT,
customer_id INT( 4 ) NOT NULL ,
account_type ENUM( 'savings', 'credit' ) NOT NULL,
balance FLOAT( 9 ) NOT NULL,
PRIMARY KEY ( account_id )
)
and
CREATE TABLE customers(
customer_id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
address VARCHAR(20) NOT NULL,
city VARCHAR(20) NOT NULL,
state VARCHAR(20) NOT NULL,
PRIMARY KEY ( customer_id )
)
How do I create a 'relationship' between the two tables? I want each account to be 'assigned' one customer_id (to indicate who owns it).
If the tables are innodb you can create it like this:
CREATE TABLE accounts(
account_id INT NOT NULL AUTO_INCREMENT,
customer_id INT( 4 ) NOT NULL ,
account_type ENUM( 'savings', 'credit' ) NOT NULL,
balance FLOAT( 9 ) NOT NULL,
PRIMARY KEY ( account_id ),
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
) ENGINE=INNODB;
You have to specify that the tables are innodb because myisam engine doesn't support foreign key. Look here for more info.
as ehogue said, put this in your CREATE TABLE
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
alternatively, if you already have the table created, use an ALTER TABLE command:
ALTER TABLE `accounts`
ADD CONSTRAINT `FK_myKey` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`customer_id`) ON DELETE CASCADE ON UPDATE CASCADE;
One good way to start learning these commands is using the MySQL GUI Tools, which give you a more "visual" interface for working with your database. The real benefit to that (over Access's method), is that after designing your table via the GUI, it shows you the SQL it's going to run, and hence you can learn from that.
CREATE TABLE accounts(
account_id INT NOT NULL AUTO_INCREMENT,
customer_id INT( 4 ) NOT NULL ,
account_type ENUM( 'savings', 'credit' ) NOT NULL,
balance FLOAT( 9 ) NOT NULL,
PRIMARY KEY ( account_id )
)
and
CREATE TABLE customers(
customer_id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
address VARCHAR(20) NOT NULL,
city VARCHAR(20) NOT NULL,
state VARCHAR(20) NOT NULL,
)
How do I create a 'relationship' between the two tables? I want each account to be 'assigned' one customer_id (to indicate who owns it).
You have to ask yourself is this a 1 to 1 relationship or a 1 out of many relationship. That is, does every account have a customer and every customer have an account. Or will there be customers without accounts. Your question implies the latter.
If you want to have a strict 1 to 1 relationship, just merge the two tables.
CREATE TABLE customers(
customer_id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
address VARCHAR(20) NOT NULL,
city VARCHAR(20) NOT NULL,
state VARCHAR(20) NOT NULL,
account_type ENUM( 'savings', 'credit' ) NOT NULL,
balance FLOAT( 9 ) NOT NULL,
)
In the other case, the correct way to create a relationship between two tables is to create a relationship table.
CREATE TABLE customersaccounts(
customer_id INT NOT NULL,
account_id INT NOT NULL,
PRIMARY KEY (customer_id, account_id),
FOREIGN KEY customer_id references customers (customer_id) on delete cascade,
FOREIGN KEY account_id references accounts (account_id) on delete cascade
}
Then if you have a customer_id and want the account info, you join on customersaccounts and accounts:
SELECT a.*
FROM customersaccounts ca
INNER JOIN accounts a ca.account_id=a.account_id
AND ca.customer_id=mycustomerid;
Because of indexing this will be blindingly quick.
You could also create a VIEW which gives you the effect of the combined customersaccounts table while keeping them separate
CREATE VIEW customeraccounts AS
SELECT a.*, c.* FROM customersaccounts ca
INNER JOIN accounts a ON ca.account_id=a.account_id
INNER JOIN customers c ON ca.customer_id=c.customer_id;
Adding onto the comment by ehogue, you should make the size of the keys on both tables match. Rather than
customer_id INT( 4 ) NOT NULL ,
make it
customer_id INT( 10 ) NOT NULL ,
and make sure your int column in the customers table is int(10) also.
Certain MySQL engines support foreign keys. For example, InnoDB can establish constraints based on foreign keys. If you try to delete an entry in one table that has dependents in another, the delete will fail.
If you are using a table type in MySQL, such as MyISAM, that doesn't support foreign keys, you don't link the tables anywhere except your diagrams and queries.
For example, in a query you link two tables in a select statement with a join:
SELECT a, b from table1 LEFT JOIN table2 USING (common_field);
Here are a couple of resources that will help get started: http://www.anchor.com.au/hosting/support/CreatingAQuickMySQLRelationalDatabase and http://code.tutsplus.com/articles/sql-for-beginners-part-3-database-relationships--net-8561
Also as others said, use a GUI - try downloading and installing Xampp (or Wamp) which run server-software (Apache and mySQL) on your computer.
Then when you navigate to //localhost in a browser, select PHPMyAdmin to start working with a mySQL database visually. As mentioned above, used innoDB to allow you to make relationships as you requested. Makes it heaps easier to see what you're doing with the database tables. Just remember to STOP Apache and mySQL services when finished - these can open up ports which can expose you to hacking/malicious threats.
One of the rules you have to know is that the table column you want to reference to has to be with the same data type as
The referencing table . 2 if you decide to use mysql you have to use InnoDB Engine because according to your question that’s the engine which supports what you want to achieve in mysql .
Bellow is the code try it though the first people to answer this question
they 100% provided great answers and please consider them all .
CREATE TABLE accounts(
account_id INT NOT NULL AUTO_INCREMENT,
customer_id INT( 4 ) NOT NULL ,
account_type ENUM( 'savings', 'credit' ) NOT NULL,
balance FLOAT( 9 ) NOT NULL,
PRIMARY KEY (account_id)
)ENGINE=InnoDB;
CREATE TABLE customers(
customer_id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
address VARCHAR(20) NOT NULL,
city VARCHAR(20) NOT NULL,
state VARCHAR(20) NOT NULL,
PRIMARY KEY ( account_id ),
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
)ENGINE=InnoDB;
create table departement(
dep_id int primary key auto_increment,
dep_name varchar(100) not null,
dep_descriptin text,
dep_photo varchar(100) not null,
dep_video varchar(300) not null
);
create table newsfeeds(
news_id int primary key auto_increment,
news_title varchar(200) not null,
news_description text,
news_photo varchar(300) ,
news_date varchar(30) not null,
news_video varchar(300),
news_comment varchar(200),
news_departement int foreign key(dep_id) references departement(dep_id)
);