mysql foreign key insert - mysql

Using this two tables i'm trying to create a query to insert a new course, but i'm using a foreign key and I don't know how to pass that users(table) id into courses(table) id.
I'm trying to get something like this
I'm completely lost, on how to insert data into a table that contains a foreign key,
what i'm trying to do is:
first a person can register(user table)
2.Then the user will be available to add courses ( im using the foreign key to identify the courses for a specific user)
Users table
id | username |
---------------
1 | test |
Courses table
coursesid | coursesname | id(same id that in users table)
1 | courses test| 1
The Create Table commands are
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`password` char(64) COLLATE utf8_unicode_ci NOT NULL,
`salt` char(16) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1;
CREATE TABLE `course` (
`courseid` int(11) NOT NULL AUTO_INCREMENT,
`coursename` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`id` int(11) NOT NULL,
UNIQUE KEY (`courseid`)
FOREIGN KEY (od) REFERENCES users(id)
)

You can use subquery for find user id, e.g.:
insert into course
(courseid, coursename, id)
values
(1, 'test courses',
(SELECT id FROM users where username = 'test')
)
;
Of cause, if you know user id, you can insert directly this id:
insert into course
(courseid, coursename, id)
values
(1, 'test courses', 1)
;
Additional query for insert just last user id:
insert into course
(courseid, coursename, id)
values
(1, 'test courses',
(SELECT max(id) FROM users)
)
;

Related

Unique Key on two table

is it possible to make two tables have a unique key like if my first table has the unique key and the second table cannot have the same text as the first table, it is possible to make that?
--
-- Table structure for table admin
DROP TABLE IF EXISTS admin;
CREATE TABLE IF NOT EXISTS admin (
ID varchar(11) NOT NULL,
Name varchar(100) NOT NULL,
Password varchar(100) NOT NULL,
Email varchar(100) NOT NULL,
PhoneNumber varchar(255) NOT NULL,
UniqueCode varchar(255) NOT NULL,
PRIMARY KEY (ID),
UNIQUE KEY UniqueCode (UniqueCode)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Dumping data for table admin
INSERT INTO admin (ID, Name, Password, Email, PhoneNumber, UniqueCode) VALUES
('AA11', 'Admin Low', '827ccb0eea8a706c4c34a16891f84e7b', 'AA11#gmail.com', '6012346778', 'Lmao'),
('AA12', 'Admin Tyler', '827ccb0eea8a706c4c34a16891f84e7b', 'AA11#gmail.com', '6033556778', 'Rofl');
--
-- Table structure for table lecturer
DROP TABLE IF EXISTS lecturer;
CREATE TABLE IF NOT EXISTS lecturer (
ID varchar(11) NOT NULL,
Name varchar(100) NOT NULL,
Password varchar(100) NOT NULL,
Email varchar(100) NOT NULL,
PhoneNumber varchar(255) NOT NULL,
UniqueCode varchar(255) NOT NULL,
PRIMARY KEY (ID),
UNIQUE KEY UniqueCode (UniqueCode)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Dumping data for table lecturer
INSERT INTO lecturer (ID, Name, Password, Email, PhoneNumber, UniqueCode) VALUES
('AL11', 'Cat Eat my son', '827ccb0eea8a706c4c34a16891f84e7b', 'AL11#gmail.com', '6012342222', 'Meow'),
('AL12', 'Dog Eat my son', '827ccb0eea8a706c4c34a16891f84e7b', 'AL12#gmail.com', '6033345678', 'Woof');
You can simply check before inserting data by useng "EXIST".
The EXISTS operator is used to test for the existence of any record in a subquery.
The EXISTS operator returns TRUE if the subquery returns one or more records.
SELECT column_name(s)
FROM table_name
WHERE EXISTS
(SELECT column_name FROM table_name WHERE condition);

Auto increment Id value increased by 1 after insert trigger

I have 3 tables as below:
CREATE TABLE `user_dummy` (
`user_id` INT(11) NOT NULL AUTO_INCREMENT,
`user_name` VARCHAR(50) NOT NULL,
`user_email` VARCHAR(100) NOT NULL,
PRIMARY KEY (`user_id`)
)
ENGINE=InnoDB
;
CREATE TABLE `user_role` (
`user_role_id` INT(11) NOT NULL AUTO_INCREMENT,
`user_role_name` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`user_role_id`)
)
ENGINE=InnoDB
;
CREATE TABLE `user` (
`user_seq` INT(11) NOT NULL AUTO_INCREMENT,
`user_id` INT(11) NOT NULL,
`user_name` VARCHAR(50) NOT NULL,
`user_email` VARCHAR(100) NOT NULL,
`user_role_id` INT(11) NOT NULL,
PRIMARY KEY (`user_seq`),
INDEX `FKh2wc2dtfdo8maylne7mgubowq` (`user_role_id`),
CONSTRAINT `FKh2wc2dtfdo8maylne7mgubowq` FOREIGN KEY (`user_role_id`) REFERENCES `user_role` (`user_role_id`) ON UPDATE CASCADE ON DELETE CASCADE
)
ENGINE=InnoDB
;
I have created after insert trigger on user table.
i.e., when I insert 1 record into user_dummy table, it will insert records into table user table with all mappings of user_role.
trigger:
CREATE TRIGGER `user_dummy_after_insert` AFTER INSERT ON `user_dummy` FOR EACH ROW BEGIN
INSERT INTO user(user_id, user_name, user_email, user_role_id)
SELECT NEW.user_id, NEW.user_name, NEW.user_email, user_role_id
FROM user_role;
END
Above trigger is able to insert records into user table but the auto_increment value is incremented by 1 after each user_role record.
If you observe user_seq 3 is missing. And after inserting 4 records, auto_increment value set by trigger as 7.
How to fix this ?
Just an alternative: Better you could use the count function to count the total existing records and then increase it by one and assign according as. If you are interested to preserve the insertion sequence.

Mysql complex select statement

I have a case which seems very complex to me and I am currently doing it in 3 queries and with lots of application logic. I thought, it may be possible with only one single queries.
I have a three table,
1. conversations table
2. chats table
3. users table
Please see the two pictures so that you can see the entities with the actual data.
conversations table
chats table
Please look at the conversation table. Here I want to get all the rows where sender=1 or reciever=1 so expected results will be
id 3,4,5. Now, I also return the user details from these selected rows.
Here is the most difficult part for me. I don't want to retrieve users details of id 1 instead I want users details whose id are 2,3 and 4 notice 4 in sender column and 2 3 in reciever column
Now, you know the selected rows from conversations table. In second table, con_id is the foreign key of conversation table so I want to retrieve the last rows of each con_id. In the second picture, you can see id 2,3,4,5,6 has con_id = 3 but since I want the last one so it should select where id = 6 similarly all last row of each con_id
I am sorry for this long case, hope you got me and the problem.
Thanks in advance.
EDIT
Here is the sql tables and dummy data for you so that if you want you can test paste quickly
Expected results
id || sender || reciver || id(users id) || userName || id(chats id) || con_id || msg || msg_sender
3 1 2 2 iamsadek2 6 3 ... 2
4 1 3 3 sadek3 10 4 ... 3
5 4 1 4 adek4. 14. 5. ... 4
DROP TABLE IF EXISTS `chats`;
CREATE TABLE `chats` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`msg_sender` int(10) unsigned DEFAULT NULL,
`con_id` int(10) unsigned DEFAULT NULL,
`msg` text,
`file` varchar(255) DEFAULT NULL,
`deleted` int(10) unsigned DEFAULT NULL,
`seen` tinyint(1) DEFAULT '0',
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `con_id` (`con_id`),
KEY `msg_sender` (`msg_sender`),
CONSTRAINT `chats_ibfk_1` FOREIGN KEY (`con_id`) REFERENCES `conversations` (`id`) ON DELETE CASCADE,
CONSTRAINT `chats_ibfk_2` FOREIGN KEY (`msg_sender`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
LOCK TABLES `chats` WRITE;
/*!40000 ALTER TABLE `chats` DISABLE KEYS */;
INSERT INTO `chats` (`id`, `msg_sender`, `con_id`, `msg`, `file`, `deleted`, `seen`, `created_at`, `updated_at`)
VALUES
(2,1,3,'id 1 sending msg to id 2',NULL,NULL,0,'2018-06-26 19:36:06',NULL),
(4,2,3,'id 2 sending msg to id 1 second msg',NULL,NULL,0,'2018-06-26 19:36:37',NULL),
(5,1,3,'id 1 sending msg to id 2 msg 3',NULL,NULL,0,'2018-06-26 19:36:42',NULL),
(6,2,3,'id 2 sending msg to id 1 msg 4',NULL,NULL,0,'2018-06-26 19:36:46',NULL),
(7,1,4,'id 1 sending msg to id 3 msg 1',NULL,NULL,0,'2018-06-26 19:36:49',NULL),
(8,3,4,'id 3 sending msg to id 1 msg 2am',NULL,NULL,0,'2018-06-26 19:39:44',NULL),
(9,3,4,'id 3 sending msg to id 1 msg 3',NULL,NULL,0,'2018-06-26 19:39:55',NULL),
(10,3,4,'id 3 sending msg to id 1 msg 4',NULL,NULL,0,'2018-06-26 19:39:57',NULL),
(11,4,5,'id 4 sending msg to id 1 msg 1',NULL,NULL,0,'2018-06-26 19:40:46',NULL),
(12,4,5,'id 4 sending msg to id 1 msg 1',NULL,NULL,0,'2018-06-26 19:40:48',NULL),
(13,4,5,'id 4 sending msg to id 1 msg 3',NULL,NULL,0,'2018-06-26 19:40:50',NULL),
(14,1,5,'id 1 sending msg to id 4 msg 4',NULL,NULL,0,'2018-06-26 19:41:01',NULL),
(15,4,11,'id 4 sending msg to id 3 msg 1',NULL,NULL,0,'2018-06-26 19:42:37',NULL),
(16,3,11,'id 3 sending msg to id 4 msg 2',NULL,NULL,0,'2018-06-26 19:42:57',NULL),
(17,3,11,'id 3 sending msg to id 4 msg 2',NULL,NULL,0,'2018-06-26 19:42:59',NULL);
/*!40000 ALTER TABLE `chats` ENABLE KEYS */;
UNLOCK TABLES;
# Dump of table conversations
# ------------------------------------------------------------
DROP TABLE IF EXISTS `conversations`;
CREATE TABLE `conversations` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`sender` int(10) unsigned DEFAULT NULL,
`reciever` int(10) unsigned DEFAULT NULL,
`status` tinyint(1) DEFAULT '0',
`type` tinyint(1) DEFAULT '0',
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `sender` (`sender`),
KEY `reciever` (`reciever`),
CONSTRAINT `conversations_ibfk_1` FOREIGN KEY (`sender`) REFERENCES `users` (`id`) ON DELETE CASCADE,
CONSTRAINT `conversations_ibfk_2` FOREIGN KEY (`reciever`) REFERENCES `users` (`id`) ON DELETE CASCADE,
CONSTRAINT `conversations_reciever_foreign` FOREIGN KEY (`reciever`) REFERENCES `users` (`id`),
CONSTRAINT `conversations_sender_foreign` FOREIGN KEY (`sender`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
LOCK TABLES `conversations` WRITE;
/*!40000 ALTER TABLE `conversations` DISABLE KEYS */;
INSERT INTO `conversations` (`id`, `sender`, `reciever`, `status`, `type`, `created_at`, `updated_at`)
VALUES
(3,1,2,0,0,'2018-06-26 19:32:35',NULL),
(4,1,3,0,0,'2018-06-26 19:32:50',NULL),
(5,4,1,0,0,'2018-06-26 19:33:11',NULL),
(6,2,3,0,0,'2018-06-26 19:33:22',NULL),
(11,3,4,0,0,'2018-06-26 19:33:22',NULL);
/*!40000 ALTER TABLE `conversations` ENABLE KEYS */;
UNLOCK TABLES;
# Dump of table users
# ------------------------------------------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`firstName` varchar(255) NOT NULL,
`lastName` varchar(255) NOT NULL,
`profilePic` varchar(255) DEFAULT 'user.png',
`address` varchar(255) DEFAULT NULL,
`lat` varchar(255) DEFAULT NULL,
`lang` varchar(255) DEFAULT NULL,
`ip` varchar(255) DEFAULT NULL,
`password` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`userName` varchar(255) NOT NULL,
`gender` varchar(11) DEFAULT NULL,
`userType` varchar(255) DEFAULT 'User',
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`status` varchar(11) DEFAULT 'active',
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`),
UNIQUE KEY `users_username_unique` (`userName`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
LOCK TABLES `users` WRITE;
/*!40000 ALTER TABLE `users` DISABLE KEYS */;
INSERT INTO `users` (`id`, `firstName`, `lastName`, `profilePic`, `address`, `lat`, `lang`, `ip`, `password`, `email`, `userName`, `gender`, `userType`, `created_at`, `updated_at`, `status`)
VALUES
(1,'sadek','hossain','user.png',NULL,NULL,NULL,NULL,'$2a$10$ayAJE7BxkgqXPGjVxeD8iu0GVWL6CXJFdLhGcHAN.i39lCqcAR5nS','sadek.hkm#gmail.com','iamsadek','male','User','2018-06-26 18:33:16','2018-06-26 18:33:16','active'),
(2,'sadek2','hossain2','user.png',NULL,NULL,NULL,NULL,'$2a$10$q.LNN48POO9g1INdEC/iTO1CJjGXNBLYZPbHkyRe.oHaZJi9b8GWe','sadek2.hkm#gmail.com','iamsadek2','male','User','2018-06-26 18:42:53','2018-06-26 18:42:53','active'),
(3,'sadek3','hossain3','user.png',NULL,NULL,NULL,NULL,'$2a$10$7xgKQDUw/tA6f8zb0uqSN.z7RnNuUVAoMuB6Eknm/cqzXk7BDcmIi','sadek3#gmail.com','sadek3','male','User','2018-06-26 19:02:30','2018-06-26 19:02:30','active'),
(4,'sadek3','hossain3','user.png',NULL,NULL,NULL,NULL,'$2a$10$7xgKQDUw/tA6f8zb0uqSN.z7RnNuUVAoMuB6Eknm/cqzXk7BDcmIi','sadek4#gmail.com','sadek4','male','User','2018-06-26 19:02:30','2018-06-26 19:02:30','active'),
(5,'sadek3','hossain3','user.png',NULL,NULL,NULL,NULL,'$2a$10$7xgKQDUw/tA6f8zb0uqSN.z7RnNuUVAoMuB6Eknm/cqzXk7BDcmIi','sadek5#gmail.com','sadek5','male','User','2018-06-26 19:02:30','2018-06-26 19:02:30','active'),
(6,'sadek3','hossain3','user.png',NULL,NULL,NULL,NULL,'$2a$10$7xgKQDUw/tA6f8zb0uqSN.z7RnNuUVAoMuB6Eknm/cqzXk7BDcmIi','sadek6#gmail.com','sadek6','male','User','2018-06-26 19:02:30','2018-06-26 19:02:30','active');
/*!40000 ALTER TABLE `users` ENABLE KEYS */;
UNLOCK TABLES;
It can basically be done with some joins. The tricky part is the last message for chats. The subquery groups the chats by the con_id to get the maximum id. As id is AUTO_INCREMENT, the maximum id for a con_id is the last message of the conversation.
SELECT co1.id,
co1.sender,
co1.reciever,
us.id "id(users id)",
us.username,
ch1.id "id(chats id)",
ch1.con_id,
ch1.msg,
ch1.msg_sender
FROM conversations co1
INNER JOIN users us
ON CASE
WHEN co1.sender <> 1
THEN co1.sender
WHEN co1.reciever <> 1
THEN co1.reciever
END = us.id
INNER JOIN chats ch1
ON ch1.con_id = co1.id
INNER JOIN (SELECT max(ch2.id) id,
ch2.con_id
FROM chats ch2
GROUP BY ch2.con_id) ch3
ON ch3.con_id = ch1.con_id
AND ch3.id = ch1.id
WHERE 1 IN (co1.sender,
co1.reciever);
SQL Fiddle
Instead of an INNER JOIN with the subquery with the GROUP BY, a correlated subyquery would be another option.
SELECT co1.id,
co1.sender,
co1.reciever,
us.id "id(users id)",
us.username,
ch1.id "id(chats id)",
ch1.con_id,
ch1.msg,
ch1.msg_sender
FROM conversations co1
INNER JOIN users us
ON CASE
WHEN co1.sender <> 1
THEN co1.sender
WHEN co1.reciever <> 1
THEN co1.reciever
END = us.id
INNER JOIN chats ch1
ON ch1.con_id = co1.id
WHERE 1 IN (co1.sender,
co1.reciever)
AND ch1.id = (SELECT max(ch2.id)
FROM chats ch2
WHERE ch2.con_id = co1.id);
SQL Fiddle
TRy it now
SELECT id.conversations, sender.conversations, receiver.conversations, id.users, userName.users, id.chats, con_id.chats, msg.chats, msg_sender.chats
FROM conversations, chats, users
WHERE (sender.conversations OR receiver.conversations = 1) AND id.conversations=firstname.users
GROUP BY id.conversations

PHP SQL Inner Join or Union

I want to select different fields from two different tables My users table and my address table as shown below:
my users table:
CREATE TABLE IF NOT EXISTS `users` (
`ID` int(3) NOT NULL AUTO_INCREMENT,
`AccountNumber` int(8) NOT NULL,
`FirstName` text NOT NULL,
`LastName` text NOT NULL,
`EmailAddress` varchar(200) NOT NULL,
`Password` varchar(200) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `AccountNumber` (`AccountNumber`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
INSERT INTO `users` (`ID`, `AccountNumber`, `FirstName`, `LastName`, `EmailAddress`, `Password`) VALUES
(1, 123456, 'test', 'test', 'test#test.ac.uk', '$2y$10$/j9nTE5ugmyrWuV8VNWFxe5iHInqyaTwxt5wDaxyQwPUZTDDjqNKm');
my address table:
CREATE TABLE IF NOT EXISTS `address` (
`AddID` int(4) NOT NULL AUTO_INCREMENT,
`HouseNumber` int(11) NOT NULL,
`StreetName` varchar(200) NOT NULL,
`City` varchar(200) NOT NULL,
`Postcode` varchar(8) NOT NULL,
`AccountNumber` int(8) NOT NULL,
PRIMARY KEY (`AddID`),
KEY `AccountNumber` (`AccountNumber`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
INSERT INTO `address` (`AddID`, `HouseNumber`, `StreetName`, `City`, `Postcode`, `AccountNumber`) VALUES
(1, 123, 'Some Road', 'someCity', 'b66', 123456);
ALTER TABLE `address`
ADD CONSTRAINT `address_ibfk_1` FOREIGN KEY (`AccountNumber`) REFERENCES `users` (`AccountNumber`);
Ive manage to use the following inner join successfully:
SELECT * FROM users INNER JOIN address ON users.AccountNumber=address.AccountNumber
However that also seems to retrieve the auto incremented ID's as well as the password field which i dont want.
I tried union but kept getting the error about different number of columns. How would i change my select statement to only retrieve the FirstName, LastName and EmailAddress from the users table and the HouseNumber, Street, City and Postcode from the address table based on the account number stored in both tables.
Any info will be appreciated
Thanks!
Try this u will get the result
SELECT FirstName,LastName,EmailAddress,HouseNumber,
Street, City, Postcode FROM users
INNER JOIN address ON users.AccountNumber=address.AccountNumber
instead of select *, just list out the columns youd like
SELECT u.FirstName,u.LastName,u.EmailAddress,a.HouseNumber,a.StreetName,a.City,a.Postcode
FROM users u
INNER JOIN address a
ON u.AccountNumber=a.AccountNumber
from there you can add a where statement if you want to limit it down to one AccountNumber:
SELECT u.FirstName,u.LastName,u.EmailAddress,a.HouseNumber,a.StreetName,a.City,a.Postcode
FROM users u
INNER JOIN address a
ON u.AccountNumber=a.AccountNumber
WHERE u.AccountNumber=12345

Insert error 1241

I have two MySQL INNODB tables 'student' and 'instructor'. They are analogous in almost every single way. I can add arbitrary records into the 'student' table, but not the 'instructor' table. Both tables have the same structure with ID as the primary key.
(ID varchar, name varchar, dept_name, varchar, field4 int)
I have tried queries such as
INSERT INTO instructor VALUES ('12345', 'name', 'computer science', 50000);
INSERT INTO instructor SET ID = 67890, name = 'Polson', dept_name = 'Bioinformatics', salary = 100 ON DUPLICATE KEY SET name = 'Polson', dept_name = 'Bioinformatics', salary = 100;
INSERT INTO instructor (ID) VALUES ('12345');
INSERT INTO instructor (ID) VALUE ('12345');
while all of these queries work with the 'student' table. What is going on?
Here are my create table statements. My user has full permissions. Is there any status query that I should use to look for issues? Thank you!
CREATE TABLE `instructor` (
`ID` varchar(5) NOT NULL DEFAULT '',
`name` varchar(20) DEFAULT NULL,
`dept_name` varchar(25) DEFAULT NULL,
`salary` decimal(10,2) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `dept_name` (`dept_name`),
CONSTRAINT `instructor_ibfk_1` FOREIGN KEY (`dept_name`) REFERENCES `department` (`dept_name`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE `student` (
`ID` varchar(10) NOT NULL DEFAULT '',
`name` varchar(20) DEFAULT NULL,
`dept_name` varchar(25) DEFAULT NULL,
`total_credits` int(11) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `dept_name` (`dept_name`),
CONSTRAINT `student_ibfk_1` FOREIGN KEY (`dept_name`) REFERENCES `department` (`dept_name`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE department (
dept_name varchar(25) NOT NULL DEFAULT '',
building varchar(15) DEFAULT NULL,
budget float(12,2) DEFAULT NULL,
PRIMARY KEY (dept_name)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
which contains a record Bioinformatics | DBI | 1000000.00