Mysql changing column from 'allow null' to 'not null' and setting value - mysql

CREATE TABLE `product` (
`product_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`category_id` int(10) unsigned DEFAULT NULL,
CONSTRAINT `product_category` FOREIGN KEY (`category_id`) REFERENCES `category` (`category_id`),
) ENGINE=InnoDB;
CREATE TABLE `category` (
`category_id` int(10) unsigned NOT NULL AUTO_INCREMENT
) ENGINE=InnoDB;
INSERT INTO `category` VALUES (1), (2);
INSERT INTO `product` (`product_id`, `category_id`) VALUES (1, 1), (2,2), (3, NULL);
I want to change definition of column category_id to forbid NULL values and make value 1 as default value.
I'm running following query:
ALTER TABLE `product` CHANGE `category_id` `category_id` INT(10) UNSIGNED NOT NULL DEFAULT 1;
Table product containts next values (after successful alter query):
1 1
2 2
3 0
Desired result:
1 1
2 2
3 1
FOREIGN_KEY_CHECKS is set to 1 and doesn't change.
Could someone explain why 0 is being set instead of 1.

Thats why the undefined value for an unsigned int is zero. The default value is only used at insertstatement.

Related

Update a variable in a mysql table depending on a time difference

CONTEXT
I would like to update a variable inside a table depending on a time difference.
DATA
I have the following mySQL Table
CREATE TABLE `userTP` (
`id` int(11) NOT NULL,
`profile` int(11) NOT NULL DEFAULT '1',
`username` varchar(50) NOT NULL,
`inprogress` int(11) NOT NULL,
`launchedat` datetime DEFAULT NULL,
`password` varchar(255) NOT NULL,
`npoints` int(11) NOT NULL DEFAULT '100',
`ms` int(11) NOT NULL DEFAULT '5000'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `userTP` (`id`, `profile`, `username`, `inprogress`, `launchedat`, `password`, `npoints`, `ms`) VALUES
(4, 0, 'binome1', 1, '2020-11-10 17:20:07', 'vvvvv', 10, 1000),
(48, 0, 'binome2', 0, '2020-06-11 14:45:07', 'llll', 10, 1000);
ALTER TABLE `userTP`
ADD PRIMARY KEY (`id`);
ALTER TABLE `userTP`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=49;
COMMIT;
WHAT I WOULD LIKE TO DO
If the time difference between launchedat and the current time is larger than 10 minutes, I would like to update the variable inprogress and set it to 2 for user with id 4
WHAT I TRIED
UPDATE userTP SET inprogress = '2' WHERE ROUND(TIME_TO_SEC(timediff(launchedat,NOW()))/60)>10 AND id = 4
This gives no error but does not work .....
Any Idea ?

Multiple Joins With Condition

I have the following schema
CREATE TABLE IF NOT EXISTS `params` (
`id` int(6) unsigned NOT NULL,
`parameter` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `entry` (
`id` int(6) unsigned NOT NULL,
`param_id` int(6) unsigned NOT NULL,
`value` int(6) unsigned NOT NULL,
`access_id` int(6) unsigned NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `enabled` (
`id` int(6) unsigned NOT NULL,
`param_id` int(6) unsigned NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `params` (`id`, `parameter`) VALUES
('1','Height'),
('2', 'Weight'),
('3', 'Texture'),
('4', 'Colour');
INSERT INTO `entry` (`id`, `param_id`,`value`,`access_id`) VALUES
('1','1','5.2','1'),
('2','2','80','2'),
('3','1','6','2');
INSERT INTO `enabled` (`id`, `param_id`) VALUES
('1','1'),('2','2');
I am trying to get all parameter values with access_id of 1 from the entry table
OR
All Parameters that are enabled which (DOES NOT exist in the entry table with access_idof 1)
So the output should be
id parameter value access_id
1 Height 5 1
2 Weight NULL NULL
The second entry here has a value of null because although it is enabled it does not have an access_id of 1 in the entry table
The schema here http://sqlfiddle.com/#!9/103016
select p.*, e.value, e.access_id from params p
inner join entry e on p.id= e.param_id and e.access_id = 1
union
select p.*, null,null from params p
inner join enabled enb on p.id=enb.param_id
where enb.param_id not in (select param_id from entry where access_id = 1)

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 joining 2 tables in to one main table

I have 2 tables 'cat' and 'sub_cat' and these two tables should join or something with main table 'product'
I tried all joining methods and non of them gave me right result I want.
I'm sure there is a method. I don't know what to call.
Sample SQL
This is how the last query should be
forget about the normalization theories and every thing and I just want the last query to be like this or mysql method that I can use on this.
cat_id cannot be duplicate
s_id should also cannot be duplicate
like in third row there can be: cat_id but no s_id the s_id should be null
if there is no cat_id and no s_id both should be null like fourth row
p_id can be duplicate
can't use group by or distinct cause it doesn't give null values then as i know
only method i got closer is using left joining both cat and sub_cat to prod table but it gives me duplicate cat_id and s_id and can't use group by or distinct on this cause there should be null values.
here is the test data
CREATE TABLE IF NOT EXISTS `cat` (
`product_id` int(11) DEFAULT NULL,
`cat_id` int(11) DEFAULT NULL,
`cat_name` varchar(10) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `cat` (`product_id`, `cat_id`, `cat_name`) VALUES
(1, 1, 'cat1'),
(2, 2, 'cat2'),
(3, 3, 'cat3'),
(1, 4, 'ca4');
CREATE TABLE IF NOT EXISTS `prod` (
`product_id` int(11) DEFAULT NULL,
`name` varchar(10) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `prod` (`product_id`, `name`) VALUES
(1, 'prod1'),
(2, 'prod2'),
(3, 'pro3'),
(4, 'prod4');
CREATE TABLE IF NOT EXISTS `sub_cat` (
`product_id` int(11) DEFAULT NULL,
`sub_cat_id` int(11) DEFAULT NULL,
`sub_cat_name` varchar(10) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `sub_cat` (`product_id`, `sub_cat_id`, `sub_cat_name`) VALUES
(1, 1, 'sub cat 1'),
(2, 2, 'sub cat 2'),
(1, 3, 'sub3');
I have done a similar thing in this one.prop_cat acts as you Category table,prop_subcat as your subcategory table and property as you product.
CREATE TABLE `prop_cat` (
`pcat_id` int(11) NOT NULL AUTO_INCREMENT,
`pcat_name` varchar(60) DEFAULT NULL,
PRIMARY KEY (`pcat_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
CREATE TABLE `prop_subcat` (
`psubcat_id` int(11) NOT NULL,
`pcat_id` int(11) NOT NULL,
`psubcat_name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`psubcat_id`,`pcat_id`),
KEY `pspc_idx` (`pcat_id`),
CONSTRAINT `catsub` FOREIGN KEY (`pcat_id`) REFERENCES `prop_cat` (`pcat_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `property` (
`prop_id` int(11) NOT NULL AUTO_INCREMENT,
`prop_name` varchar(25) DEFAULT NULL,
`price` double DEFAULT NULL,
`location` varchar(50) DEFAULT NULL,
`image` varchar(60) DEFAULT NULL,
`area` double DEFAULT NULL,
`psubcat_id` int(11) DEFAULT NULL,
`description` text,
PRIMARY KEY (`prop_id`),
KEY `psub_idx` (`psubcat_id`),
CONSTRAINT `psub` FOREIGN KEY (`psubcat_id`) REFERENCES `prop_subcat` (`pcat_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
SELECT
prop_cat.`pcat_id` AS prop_cat_pcat_id,
prop_cat.`pcat_name` AS prop_cat_pcat_name,
prop_subcat.`psubcat_id` AS prop_subcat_psubcat_id,
prop_subcat.`pcat_id` AS prop_subcat_pcat_id,
prop_subcat.`psubcat_name` AS prop_subcat_psubcat_name,
property.`prop_id` AS property_prop_id,
property.`prop_name` AS property_prop_name,
property.`price` AS property_price,
property.`location` AS property_location,
property.`image` AS property_image,
property.`area` AS property_area,
property.`psubcat_id` AS property_psubcat_id,
property.`description` AS property_description
FROM
`prop_cat` prop_cat INNER JOIN `prop_subcat` prop_subcat ON prop_cat.`pcat_id` = prop_subcat.`pcat_id`
INNER JOIN `property` property ON prop_subcat.`pcat_id` = property.`psubcat_id`

How to create INT field (not a primary key) who start at 1000 with auto_increment

I want to create a field INT(11) in my MYSQL Database who start at the value of 1000 and is incremented of 1 after each INSERT.
WARNING: THIS IS NOT A PRIMARY KEY
The DB is running with MYSQL 6.0 and InnoDB engine
Who can I achieve this, if it's possible ?
You can have an auto_increment column as long as it is defined as a key (it doesn't have to be a PRIMARY KEY). So for example:
CREATE TABLE auto_inc_test (
ID INT PRIMARY KEY,
IncValue INT AUTO_INCREMENT,
SomeData VARCHAR(50),
INDEX(IncValue)
);
ALTER TABLE auto_inc_test AUTO_INCREMENT = 1000;
(The ALTER TABLE line sets the next value for the AUTO_INCREMENT.)
If you then run the following insert (which, obviously, gives no value for the IncValue field):
INSERT INTO auto_inc_test (ID, SomeData)
VALUES (1, 'test 1'), (2, 'test 2'), (3, 'test3')
You'll get:
ID IncValue SomeData
1 1000 test 1
2 1001 test 2
3 1002 test 3
Try below code hope this should help you focus on the syntax part in below code -- KEY (id) --
CREATE TABLE IF NOT EXISTS `users`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
`email` varchar(80) NOT NULL,
`type` int(11) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
`status` enum('1','0') NOT NULL COMMENT '''0'' for inactive ''1'' for active',
PRIMARY KEY (`username`),
KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1000;