SQL AUTO_INCREMENT starting at number - mysql

am on a MySQL database and am using MySQL workbench.
here's my table DDL
CREATE TABLE `contract_validator` (
`id` bigint(20) NOT NULL,
`created` datetime(6) NOT NULL,
`user_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1
I want to make an id column in a table auto_increment, i did so using
SET FOREIGN_KEY_CHECKS = 0;
ALTER TABLE validator MODIFY id bigint AUTO_INCREMENT;
SET FOREIGN_KEY_CHECKS = 1;
I have two issues, i want to set the auto_increment to max(id) + 1
i have tried:
SELECT #validator_id := max(id) + 1 FROM validator;
ALTER TABLE validator AUTO_INCREMENT = #validator_id ;
but i get syntax error,
the second issue is that when i try to insert a line i get an error
Error Code: 1364. Field 'id' doesn't have a default value
I don't know what I did wrong,
thank you for your help.

Normally, you don't have to take care of AUTO_inCREMENT value.
When you update id column to make it auto increment, MySQL will automatically set AUTO_INCREMENT value to the MAX + 1 value, event if there are gaps in in column numerotation.
SQL for setting auto increment on id field:
ALTER TABLE `test` CHANGE `id` `id` INT(11) NOT NULL AUTO_INCREMENT, add PRIMARY KEY (`id`);

Related

Specific field parameter when creating a table MySQL

I'm using MySQL Workbench.
I would like to create a table named courseInfo and I want to put a column named moduleCode in it, but I want it to always be similar in format: CFSM H0000 where the four zeros are a number that increases starting with 0000.
For example:
CFSM H0001
CFSM H0002
[..]
You cannot auto-increment character type columns in MySQL, as auto-increment is only possible on integer type columns. One (alphanumeric) auto-incrementing moduleCode column would therefore not be possible. However, you could try splitting up the moduleCode into two columns, for example like so:
CREATE TABLE `courseInfo` (
`prefix` CHAR(6) NOT NULL DEFAULT 'CFSM H',
`id` SMALLINT(4) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT,
KEY (`id`)
) AUTO_INCREMENT = 0;
Where prefix could for example be "CFSM H" and id could be 0001
Then, upon executing SELECT statements, you could merge the prefix column with the id column into a moduleCode column with CONCAT, e.g.:
SELECT CONCAT(`prefix`, `id`) as `moduleCode` FROM `courseInfo`;
An alternative approach (from MySQL version 5.7 and up) seems to be the use of a generated column, for example:
CREATE TABLE `courseInfo` (
`prefix` CHAR(6) NOT NULL DEFAULT 'CFSM H',
`id` SMALLINT(4) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT,
`moduleCode` CHAR(10) AS (CONCAT(`prefix`, `id`)),
KEY (`id`)
) AUTO_INCREMENT = 0;
However, the above example of a generated column would not work, because moduleCode is dependent on an auto-increment column, and the auto-increment is not executed yet at the time the generated column is computed. See also: https://dev.mysql.com/doc/refman/5.7/en/create-table-generated-columns.html. It would throw an ER_GENERATED_COLUMN_REF_AUTO_INC error.
You could therefore use the first solution, or try to add moduleCode as a column and use an AFTER INSERT trigger to update its value:
CREATE TABLE `courseInfo` (
`prefix` CHAR(6) NOT NULL DEFAULT 'CFSM H',
`id` SMALLINT(4) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT,
`moduleCode` CHAR(10),
KEY (`id`),
UNIQUE KEY `unique_index` (`prefix`,`id`)
) AUTO_INCREMENT = 0;
DELIMITER //
CREATE TRIGGER `addModuleCode` AFTER INSERT ON `courseInfo`
FOR EACH ROW
BEGIN
UPDATE `courseInfo` SET `moduleCode` = CONCAT(NEW.`prefix`, NEW.`id`) WHERE `prefix` = NEW.`prefix` AND `id` = NEW.`id`;
END;//
DELIMITER ;

How to use more than 1 auto-increment column in MySQL

I want to create a table name Users where I should have have columns User, cookieID, sessionID, Geo and then I want to first three columns to have some random unique value assigned automatically. I tried to make all three columns AUTO_INCREMENT with User column PRIMARY and 'cookieIDandsessionIDcolumnUNIQUE`. The SQL code is:
CREATE TABLE `users` ( `User` VARCHAR(20) NOT NULL AUTO_INCREMENT ,
`cookieID` INT(20) NULL DEFAULT NULL AUTO_INCREMENT ,
`sessionID` INT(20) NULL DEFAULT NULL AUTO_INCREMENT ,
`Geo` VARCHAR(30) NULL DEFAULT NULL ,
PRIMARY KEY (`User`), UNIQUE (`cookieID`), UNIQUE (`sessionID`), UNIQUE (`Geo`));
But, it did not work because only one column can be declared as AUTO_INCREMENT which must be PRIMARY.
What is the another approach to do this?
Since the auto-increment cannot be applied to multiple to rows and there no option for sequence in MySQL. You can use triggers for the unique update of the row with datetime.
Change to table creation to be of single auto-increment row.
CREATE TABLE `users` ( `User` VARCHAR(20) NOT NULL,
`cookieID` INT(20) NULL DEFAULT NULL,
`sessionID` INT(20) NULL DEFAULT NULL AUTO_INCREMENT ,
`Geo` VARCHAR(30) NULL DEFAULT NULL,
PRIMARY KEY (`User`), UNIQUE (`cookieID`), UNIQUE (`sessionID`), UNIQUE (`Geo`));
Create a trigger on the same table as below. You can set the unique values under the SET for as many column as you want.
CREATE DEFINER=`root`#`localhost` TRIGGER `users_BEFORE_INSERT` BEFORE INSERT ON `users` FOR EACH ROW BEGIN
SET
NEW.cookieID = (SELECT curdate()+curtime());
END
Now when you insert into the table as below.
insert into `users`(`User`) values("test");
You table looks like this.
User cookieID sessionID Geo
test 20315169 0 NULL
If the value which are auto incrementing, you wanna keep both values the same. Then copy the value of one column to another during insertion time of new value.

How to optimize a MySQL select with rows that do not have matching values in the other table

This question is more or less the same as this one: MySQL select rows that do not have matching column in other table; however, the solution there is not not practical for large data sets.
This table has ~120,000 rows.
CREATE TABLE `tblTimers` (
`TimerID` int(11) NOT NULL,
`TaskID` int(11) NOT NULL,
`UserID` int(11) NOT NULL,
`StartDateTime` datetime NOT NULL,
`dtStopTime` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
ALTER TABLE `tblTimers`
ADD PRIMARY KEY (`TimerID`);
ALTER TABLE `tblTimers`
MODIFY `TimerID` int(11) NOT NULL AUTO_INCREMENT;
This table has about ~70,000 rows.
CREATE TABLE `tblWorkDays` (
`WorkDayID` int(11) NOT NULL,
`TaskID` int(11) NOT NULL,
`UserID` int(11) NOT NULL,
`WorkDayDate` date NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
ALTER TABLE `tblWorkDays`
ADD PRIMARY KEY (`WorkDayID`);
ALTER TABLE `tblWorkDays`
MODIFY `WorkDayID` int(11) NOT NULL AUTO_INCREMENT;
tblWorkDays should have one line per TaskID per UserID per WorkDayDate, but due to a bug, a few work days are missing despite there being timers for those days; so, I am trying to create a report that shows any timer that does not have a work day associated with it.
SELECT A.TimerID FROM tblTimers A
LEFT JOIN tblWorkDays B ON A.TaskID = B.TaskID AND A.UserID = B.UserID AND DATE(A.StartDateTime) = B.WorkDayDate
WHERE B.WorkDayID IS NULL
Doing this causes the server to time out; so, I am looking for if there is a way to do this more efficiently?
You don't have any indexes on the columns you're joining on, so it has to do full scans of both tables. Try adding the following:
ALTER TABLE tblTimers ADD INDEX (TaskID, UserID);
ALTER TABLE tblWorkDays ADD INDEX (TaskID, UserID);

Auto_increment in child tables

I'm trying to create a table to capture details of subtype variations using auto_increment but I keep get an error saying:
1075 - Incorrect table definition; there can be only one auto column and it must be defined as a key
However, I'm unsure how to capture it all correctly as I want the auto_increment of subtypes to start from 1 for each TypeId....is this not possible?
CREATE TABLE IF NOT EXISTS `types` (
`TypeID` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`TypeFeatures` TEXT NOT NULL,
PRIMARY KEY (`TypeID`))
ENGINE = InnoDB;
insert into types
(TypeFeatures)
values
(1,'Type1'),
(2,'Type2'),
(3,'Type3')
;
CREATE TABLE IF NOT EXISTS `subtypes` (
`Type_ID` INT UNSIGNED NOT NULL,
`SubtypeID` TINYINT UNSIGNED NOT NULL AUTO_INCREMENT,
`SubtypeFeatures` TEXT NOT NULL,
PRIMARY KEY(`Type_ID`,`SubtypeID`))
ENGINE = InnoDB;
insert into subtypes
(Type_ID,subtypeID,SubtypeFeatures)
values
(1,1,'Subtype1'),
(1,2,'Subtype2'),
(2,1,'Subtype1'),
(3,1,'Subtype1')
;
Thanks in advance for any suggestions!
Bendy

Mysql Auto Increment increasing by 2 and 1?

If I create a table with the following syntax,
CREATE TABLE IF NOT EXISTS `hashes` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`hash` binary(20) NOT NULL,
PRIMARY KEY (`id`,`hash`),
UNIQUE KEY (`hash`)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE = 4 AUTO_INCREMENT=1
PARTITION BY KEY(`hash`)
PARTITIONS 10;
And insert queries with the following syntax
INSERT INTO hashes (hash) VALUES ($value) ON DUPLICATE KEY UPDATE hash = hash
Then the auto increment column works as expected both if the row is inserted or updated.
Although creating the table without the partition like below and inserting with the query above the auto increment value will increase by 1 on every update or insert causing the A_I column to be all over place as the query could do 10 updates and then 1 insert causing the column value to jump 10 places.
CREATE TABLE IF NOT EXISTS `hashes` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`hash` binary(20) NOT NULL,
PRIMARY KEY (`id`,`hash`),
UNIQUE KEY (`hash`)
) ENGINE=InnoDB AUTO_INCREMENT=1;
I understand why the value increases on an update with INNO_DB but I do not understand why it doesn't when the table is partitioned?
you cannot change that, but you can try something like this:
mysql> set #a:= (select max(id) + 2 from hashes);
mysql> insert into hashes (id) values ($value) on duplicate key update id=#a;
NOTE: the partitions change a little bit after mysql 5.6, which version do you have?