MySQL JOIN to get multiple entries from same table - mysql

I have a table of users that has a user id and multiple vehicles assigned to that user. Each vehicle is an integer value that is equal to a vehicle id in a separate table. I would like to retrieve the user id and the make and model of each of the vehicles associated with that user. I can get the user id and the make and model of a single vehicle with the following query:
SELECT users.user_id, vehicles.make, vehicles.model
FROM users
JOIN vehicles ON users.vehicle1 = vehicles.vehicle_id
I have tried multiple joins, etc.. but I have can not get it to work.
Any help would be greatly appreciated.
Edited to include table structures:
I tried to include these as images but I don't have enough posts yet.
Users Table
https://www.dropbox.com/s/tbn6e0omn96m41k/users.JPG?dl=0
Vehicles Table
https://www.dropbox.com/s/8dpr22c9llbzrf2/vehicles.JPG?dl=0
I need to get the make and model of ALL vehicles associated with the user.

#vthokie11 -- Drew has a good point. Your table structure is not good.
You can refer here
I would have had a structure in the following way:
1. user table:
DROP TABLE IF EXISTS `stacktest`.`user`;
CREATE TABLE `stacktest`.`user` (
`user_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
2.vehicle table:
DROP TABLE IF EXISTS `stacktest`.`vehicle`;
CREATE TABLE `stacktest`.`vehicle` (
`vehicle_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`make` varchar(45) DEFAULT NULL,
`model` varchar(45) DEFAULT NULL,
PRIMARY KEY (`vehicle_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
3.user_vehicle table: (which maintains the relationship between user and vehicles)
DROP TABLE IF EXISTS `stacktest`.`user_vehicle`;
CREATE TABLE `stacktest`.`user_vehicle` (
`user_id` int(10) unsigned NOT NULL,
`vehicle_id` int(10) unsigned NOT NULL,
KEY `FK_user_vehicle_1` (`user_id`),
KEY `FK_user_vehicle_2` (`vehicle_id`),
CONSTRAINT `FK_user_vehicle_2` FOREIGN KEY (`vehicle_id`) REFERENCES `vehicle` (`vehicle_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_user_vehicle_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
And now you need to execute this simple query:
SELECT user.user_id, vehicle.make, vehicle.model
FROM user LEFT JOIN user_vehicle on user_vehicle.user_id=user.user_id
LEFT JOIN vehicle on vehicle.vehicle_id=user_vehicle.vehicle_id where user.user_id=1;

SELECT users.user_id, vehicles.make, vehicles.model
FROM users, vehicles
WHERE users.vehicle1 = vehicles.vehicle_id
Note: It would be better practice to name the column in the user table vehicle_id so it is clear that it is an id in another table and make it a foreign key.

Related

MySQL alter two column for same foreign key

I have a table called user and the primary key is user_id.
I have another table called follows. This table is for storing which user follow which user(it is something like twitter follow function).
This is my follow table.
CREATE TABLE `follows` (
`id` int(11) NOT NULL,
`orginal_user_id` int(11) NOT NULL,
`follow_user_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `follows`
ADD PRIMARY KEY (`id`);
So, how can I alter this table to set both orginal_user_id and follow_user_id as a foreign key of user_id of user table...
If a user is deleted from the user table, I want to automatically delete rows in follows table either that user id appears on an orginal_user_id column or follow_user_id column.
You may use cascading delete constraints in your table:
CREATE TABLE follows (
id int(11) NOT NULL PRIMARY KEY,
orginal_user_id int(11) NOT NULL,
follow_user_id int(11) NOT NULL,
CONSTRAINT fk_original_user FOREIGN KEY (orginal_user_id)
REFERENCES user(id) ON DELETE CASCADE,
CONSTRAINT fk_follow_user FOREIGN KEY (follow_user_id)
REFERENCES user(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Why should I create a MySql table containing index only?

I'm following a Java Spring tutorial to learn some basic information about the secure login in a web app.
In this tutorial, the author has created 3 MySql table to manage the authentication:
CREATE TABLE `roles` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`role` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
CREATE TABLE `users` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`login` varchar(20) NOT NULL,
`password` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
CREATE TABLE `user_roles` (
`user_id` int(6) NOT NULL,
`role_id` int(6) NOT NULL,
KEY `user` (`user_id`),
KEY `role` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The table "roles" contains the user role (for example "Admin", "User" etc...).
The table "users" contains the user login and password.
So, I can't understand why the table "user_roles" has been created! The relation between "roles" and "users" is one-to-one, so I could insert an index for these 2 tables and delete the "user_roles"...is it right?
Why should I need to join the tables "users --> user_roles --> roles" instead of "users --> roles" ?
Thanks in advance :)
For a 1:1 relationship, have just one table. (There are exceptions, but I don't see any reason for such here.)
If you have many users in each role but a user is in only one role, then add role_id to the Users table. This is 1:many. You may need INDEX(role_id).
If a user can have many roles and each role can have many users, then you need many:many. And this would be the optimal way to write the 3rd table:
CREATE TABLE `user_roles` (
`user_id` int(6) NOT NULL,
`role_id` int(6) NOT NULL,
PRIMARY KEY (`user_id`, role_id),
KEY (`role_id`, user_id)
) ENGINE=InnoDB DEFAULT;
In some sense, that is an index-only table, since the PRIMARY KEY contains all the fields.
The (6) in INT(6) is meaningless. In particular, it does not give you 6-digit integers, it still gives you 4-byte signed integers up to 2 billion. Perhaps you should use MEDIUMINT UNSIGNED for values of 0..16M. Or SMALLINT UNSIGNED for 2-byte values of 0..64K.

Creating foreign key between 2 tables

Ok, so it's like this. I have 2 tables in phpmyadmin. One is for personal details and the other is for login information. Both tables have AccountID, so I tried using foreign key constraints to connect the tables. After I did that it seems like I cannot update the table with new data. Before the constraint, updating the tables worked fine.
What I'm trying to do is store user login info and personal info in these table. Then whenever the user wants to delete their current account, the personal details and login details of are deleted from both tables or when they wanted to search for their login and personal info the search engine can search from both tables with AccountID.
so far.i have make 2 new tables.1 table which is personal information have 'AccountID'[A_I][PRIMARY] and 'loginID'.another table is login info.it has 'loginID'[A_i][PRIMARY]
i already make the 'loginID' at personal info and index but i cannot assign foreign key constraint for it bcause it did not detect 'loginID' in personal info.
Your AccountId should be a primary key in one table say Personal Info table.
This AccountId should be the foreign key in another table (Login) and make sure you set on Delete Cascade and on Update Cascade.
So in this structure, when personal info is deleted, its corresponding record in the login table will be automatically deleted.
DROP TABLE IF EXISTS `stacktest`.`personal_info`;
CREATE TABLE `stacktest`.`personal_info` (
`account_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
`age` varchar(45) DEFAULT NULL,
PRIMARY KEY (`account_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `stacktest`.`login_info`;
CREATE TABLE `stacktest`.`login_info` (
`loginId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`account_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`loginId`),
KEY `FK_login_info_1` (`account_id`),
CONSTRAINT `FK_login_info_1` FOREIGN KEY (`account_id`) REFERENCES `personal_info` (`account_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
Above is the way how the 2 tables should be created.
Then insert some values in both table,
Note that account_id value has to be same in both the tables.
After that you can fire a delete query like:
delete from personal_info where accound_id=2;
This will delete rows from parent table personal_info and also from child table login_info where account_id is 2
Keeping the account_id as NOT NULL in child table:
DROP TABLE IF EXISTS `stacktest`.`login_info`;
CREATE TABLE `stacktest`.`login_info` (
`loginId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`account_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`loginId`),
KEY `FK_login_info_1` (`account_id`),
CONSTRAINT `FK_login_info_1` FOREIGN KEY (`account_id`) REFERENCES `personal_info` (`account_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

Cannot delete or update a parent row

When I try and delete a movie from my database I get a the above error. I believe I have some how made the rated table have precedence over the films table.
How do I make the film table have precedence of the rated table
DELETE FROM `film`.`films` WHERE `films`.`movie_id` =16
--
-- Table structure for table `films`
--
CREATE TABLE IF NOT EXISTS `films` (
`movie_id` int(4) NOT NULL AUTO_INCREMENT,
`movie_title` varchar(100) NOT NULL,
`actor` varchar(100) NOT NULL,
PRIMARY KEY (`movie_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=17 ;
CREATE TABLE IF NOT EXISTS `rated` (
`rated_id` int(4) NOT NULL AUTO_INCREMENT,
`rated_name` varchar(40) NOT NULL,
`movie_id` int(4) DEFAULT NULL,
PRIMARY KEY (`rated_id`),
KEY `movie_id` (`movie_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
ALTER TABLE `rated`
ADD CONSTRAINT `rated_ibfk_1` FOREIGN KEY (`movie_id`) REFERENCES `films` (`movie_id`);
The foreign key you have defined on movie_id by default restricts the deletion: with the current schema you cannot delete a film as long as it has ratings.
You can automatically delete the ratings when you delete the film using cascading delete. Whether this is the best option for your application is for you to decide...
ALTER TABLE `rated` ADD FOREIGN KEY (`movie_id`)
REFERENCES `films` (`movie_id`) ON DELETE CASCADE;
Since there is a foreign key constraint you have to first delete any child records before you can delete the parent.
Try deleting everything from Rated table first, then deleting from films table.
DELETE FROM Rated
WHERE Movie_ID = 16
DELETE FROM Films
WHERE Movie_ID = 16

how to define foreign key constraints

I have three mysql tables. Tables are already created.
Requests - request_id, request_message, user_id
Responses - response_id, response_message, user_id
users - user_id, user_name
Now i want to define foreign key constraints on that, such that
1. If user_id is not present in Users table, and someone is inserting the data in Requests or Responses for that user_id -- then error
2. If request_id is not present in Requests table, then if someone is inserting in responses table for that request_id -- then error
3. If someone deletes an user_id, all associated requests and responses with that user_id should be deleted automatically.
4. If someone deletes an request_id, all the associated responses with it, should be deleted automatically.
If i am missing any thing please let me know.
How to achieve this functionality?
Thanks
Devesh
Here is full sql to create your tables:
CREATE TABLE IF NOT EXISTS `reponses` (
`response_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`response_message` varchar(45) DEFAULT NULL,
`user_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`response_id`,`user_id`),
KEY `fk_reponses_users1` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=3 ;
CREATE TABLE IF NOT EXISTS `requests` (
`request_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`request_message` varchar(45) DEFAULT NULL,
`user_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`request_id`,`user_id`),
KEY `fk_requests_users` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=3 ;
CREATE TABLE IF NOT EXISTS `users` (
`user_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=3 ;
ALTER TABLE `reponses`
ADD CONSTRAINT `reponses_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE NO ACTION;
ALTER TABLE `requests`
ADD CONSTRAINT `requests_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE NO ACTION;
Option that allows you to delete records related to user is ON DELETE CASCADE. By default MySql sets NO ACTION which refers to RESTRICT and doesn't allow parent record to be deleted while it has related objects. I think that you didn't mention the relation between responses and requests but you should get the idea ;).