I write a query and give a table in output but I want to every row of my table has a number automatically that starts from 1. for example , I want that my table has "number" column that first row of my table have 1 in that column , second row of my table have 2 in that column , third row of my table have 3 in that column , ...
How can I do this ?
thanks
** My DBMS is MySQL **
Use a variable and increment it like following.
set #num:=0;
select *, #num:=#num+1 `Row` from names;
Example
mysql> create table names( name varchar(10) primary key )engine=Innodb charset=utf8 collate utf8_general_ci;
Query OK, 0 rows affected (0.09 sec)
mysql> insert into names values('a'), ('b'), ('cat'), ('dog'), ('parrot'), ('bird');
Query OK, 6 rows affected (0.04 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> set #num:=0; select *, #num:=#num+1 `Row` from names;
Query OK, 0 rows affected (0.00 sec)
+--------+------+
| name | Row |
+--------+------+
| a | 1 |
| b | 2 |
| bird | 3 |
| cat | 4 |
| dog | 5 |
| parrot | 6 |
+--------+------+
6 rows in set (0.00 sec)
Note: If you use * make sure it precedes.
AUTO_INCREMENT is what you are looking for
Like this :
CREATE TABLE animals (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM;
Taken from here: http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
EDIT: Based on the comment someone might want to add that manually. You select the maximum value from your filed, increment by 1 and then insert it into your table.
SELECT MAX(id) FROM animals
Make your primary key an auto increment field.
More info here: http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
Related
So I have a table where a column that was given an auto_increment value accidentally got started form 300 instead of 1,2,3,4......i'm a beginner and i do not know how to change it back to 1,2,3,4......screenshot of table
how to change the 307, 308 to 1,2,3,4...?
I tried to update the table but that did not work.
Step-1) First take backup of your table data.
Step-2) Truncate the table by using the below SQL query.
TRUNCATE TABLE [Your_Table_Name];
Step-3) then again insert the into your table using backup data.
Alter table to drop the auto_increment, update, alter table to add the auto_increment
drop table if exists t;
create table t
( id int auto_increment primary key, val int);
insert into t values
(307,1),(308,1),(309,1),(310,1),(311,1);
alter table t
modify column id int;
#drop primary key;
show create table t;
update t
set id = id - 306;
alter table t
modify column id int auto_increment;
show create table t;
https://dbfiddle.uk/eBQh6cj8
With MySQL 8.0 you can use a window function to calculate the row numbers and then update the table:
mysql> select * from t;
+-----+------+
| id | val |
+-----+------+
| 307 | 1 |
| 308 | 1 |
| 309 | 1 |
| 310 | 1 |
| 311 | 1 |
+-----+------+
mysql> with cte as ( select id, row_number() over () as rownum from t )
-> update t join cte using (id) set id = rownum;
Query OK, 5 rows affected (0.00 sec)
Rows matched: 5 Changed: 5 Warnings: 0
mysql> select * from t;
+----+------+
| id | val |
+----+------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 5 | 1 |
+----+------+
Then make sure the next id won't be a high value:
mysql> alter table t auto_increment=1;
You can try to set the auto_increment to 1, MySQL will automatically advances that to the highest id value in the table, plus 1.
Be aware that this doesn't guarantee subsequent rows will use consecutive values. You can get non-consecutive values if:
You insert greater values explicitly, overriding the auto-increment.
You roll back transactions. Id values generated by auto-increment are not recycled if you roll back.
You delete rows.
Occasionally InnoDB will skip a number anyway. It does not guarantee consecutive values — it only guarantees unique values. You should not rely on the auto-increment to be the same as a row number.
Here is a one approach to your problem.
Please take note of the following points before proceeding:
Take backup of your table in-case things do not go as expected.
Below test case has been performed on MySQL 5.7 and MyISAM Engine.
Step1: Generating dummy test table as per your test case.
mysql> CREATE TABLE t (
-> `Id` int(11) NOT NULL AUTO_INCREMENT,
-> `product_id` int(11) DEFAULT 0,
-> PRIMARY KEY (`Id`)
-> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.03 sec)
-- Inserting dummy data
mysql> INSERT INTO t VALUES (300,1);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO t VALUES (302,1);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO t VALUES (305,1);
Query OK, 1 row affected (0.00 sec)
-- Checking auto_increment value
mysql> show create table t;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t | CREATE TABLE `t` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(11) DEFAULT '0',
PRIMARY KEY (`Id`)
) ENGINE=MyISAM AUTO_INCREMENT=306 DEFAULT CHARSET=latin1 |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> INSERT INTO t (product_id) VALUES (2);
Query OK, 1 row affected (0.01 sec)
-- Below is the resultant table for which we need Id starting from 1,2,3 and so on...
mysql> SELECT * FROM t;
+-----+------------+
| Id | product_id |
+-----+------------+
| 300 | 1 |
| 302 | 1 |
| 305 | 1 |
| 306 | 2 |
+-----+------------+
4 rows in set (0.00 sec)
Step2: Remove AUTO_INCREMENT for the column and set the Ids manually.
-- Remove AUTO_INCREMENT
mysql> ALTER TABLE t MODIFY COLUMN Id int(11) NOT NULL;
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
-- Set the Id manually starting from 1
mysql> SET #i = 0;UPDATE t SET id = #i :=#i +1;
Query OK, 0 rows affected (0.00 sec)
Query OK, 5 rows affected (0.00 sec)
Rows matched: 5 Changed: 5 Warnings: 0
-- Below is the updated table with Id starting from 1,2,3 and so on...
mysql> SELECT * FROM t;
+----+------------+
| Id | product_id |
+----+------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
+----+------------+
5 rows in set (0.00 sec)
Step3: Enable AUTO_INCREMENT again for future record insertions.
-- Enable AUTO_INCREMENT again for future record insertions.
mysql> ALTER TABLE t MODIFY COLUMN Id int(11) NOT NULL AUTO_INCREMENT;
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
-- Set the AUTO_INCREMENT value to continue from highest value of id in the table.
mysql> SELECT MAX(id+1) FROM t;
+-----------+
| MAX(id+1) |
+-----------+
| 6 |
+-----------+
1 row in set (0.00 sec)
mysql> ALTER TABLE t AUTO_INCREMENT=6;
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
-- Table is successfully modified and will have future records inserted with no gaps in Id's
mysql> INSERT INTO t (product_id) VALUES (5);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM t;
+----+------------+
| Id | product_id |
+----+------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 5 |
+----+------------+
6 rows in set (0.00 sec)
The DBCC CHECKIDENT management command is used to reset identity counter
DBCC CHECKIDENT (table_name [, { NORESEED | { RESEED [, new_reseed_value]}}])
[ WITH NO_INFOMSGS ]
EXample:
DBCC CHECKIDENT ('TestTable', RESEED, 0)
GO
many times we need to just reseed to next Id available
declare #max int
select #max=max([Id]) from [TestTable]
if #max IS NULL --check when max is returned as null
SET #max = 0
DBCC CHECKIDENT ('[TestTable]', RESEED, #max)
This will check the table and reset to the next ID.
You can get help from the link below:
Reset identity seed after deleting records in SQL Server
My mother says: the mountain that can be seen is not far away, don't stop trying
I have a table like this:
id | name
--------------
1 | John
2 | Mary
.
.
.
NULL | Brian
NULL | Jacob
I meant to make id an AUTO INCREMENT row, but I guess I did not b/c when I added new names Brian, Jacob, it didn't automatically add incremented id values. I am wondering if there is a way to add those values to replace NULL, without changing any of the id's above it.
Demo:
mysql> create table mytable (id int, name text);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into mytable values
-> (1, 'John'),
-> (2, 'Mary'),
-> (NULL, 'Brian'),
-> (NULL, 'Jacob');
Query OK, 4 rows affected (0.01 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> alter table mytable modify column id int auto_increment, add primary key (id);
Query OK, 4 rows affected (0.02 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from mytable;
+----+-------+
| id | name |
+----+-------+
| 1 | John |
| 2 | Mary |
| 3 | Brian |
| 4 | Jacob |
+----+-------+
4 rows in set (0.00 sec)
Conclusion: Yes.
You do need id to be the first column in a key (I used PRIMARY KEY here). MySQL's InnoDB storage engine won't let a column be auto-increment unless it's the leftmost column in some key (that is, any index will suffice).
Database-1
create table sample (
id INT,
nm VARCHAR(10)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
UNION=(for tables from another databases);
So, when we do union what actually it meance?
Please explain, I am getting confusing for this type of UNION.
That looks close to the syntax for creating a merge table, but it has the engine type wrong. Your statement will ignore the union clause and simply create a new, empty table. In order to create merge table you need to specify ENGINE=MERGE.
14.3 The MERGE Storage Engine
The MERGE storage engine, also known as the MRG_MyISAM engine, is a
collection of identical MyISAM tables that can be used as one.
The tables you specify in the UNION clause there, must all be identical - ie, having the same index and column specification, and they must all be in the same order in each table.
After that, can you query your merge table and access the data from all of the tables that form it.
You can also insert into your merge table, which is something you cannot do with a view:
You can optionally specify an INSERT_METHOD option to control how
inserts into the MERGE table take place. Use a value of FIRST or LAST
to cause inserts to be made in the first or last underlying table,
respectively. If you specify no INSERT_METHOD option or if you specify
it with a value of NO, inserts into the MERGE table are not permitted
and attempts to do so result in an error.
Anyway, the doco has the rest of the information if you want to peruse more - I've never felt the need to use this type of table.
Example:
mysql>
mysql> create table t2 (
-> id integer primary key auto_increment,
-> val char(20)
-> ) engine=myisam;
Query OK, 0 rows affected (0.05 sec)
mysql>
mysql> insert into t1(val) values ('table1 a'), ('table1 b');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> insert into t2(val) values ('table2 a'), ('table2 b');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql>
mysql>
mysql> create table mt (
-> id integer primary key auto_increment,
-> val char(20)
-> ) engine=merge union=(t1,t2) insert_method=last;
Query OK, 0 rows affected (0.04 sec)
mysql>
mysql> select * from mt;
+----+----------+
| id | val |
+----+----------+
| 1 | table1 a |
| 2 | table1 b |
| 1 | table2 a |
| 2 | table2 b |
+----+----------+
4 rows in set (0.00 sec)
mysql> insert into mt(val) values ('12345');
Query OK, 1 row affected (0.00 sec)
mysql> select * from mt;
+----+----------+
| id | val |
+----+----------+
| 1 | table1 a |
| 2 | table1 b |
| 1 | table2 a |
| 2 | table2 b |
| 3 | 12345 |
+----+----------+
5 rows in set (0.01 sec)
mysql> select * from t2;
+----+----------+
| id | val |
+----+----------+
| 1 | table2 a |
| 2 | table2 b |
| 3 | 12345 |
+----+----------+
3 rows in set (0.00 sec)
I have a MySQL database with tables t1 and t2. One of the columns in table t1 has a foreign key to t2.
Need to allow the foreign key column to accept null values. There is already some important data so recreating the table is not an option.
Tried the usual alter table commands but it showed syntax error.
Is there a way to go around it without affecting the database?
This is what I tried:
ALTER TABLE t1 MODIFY fk_column_id NULL;
The missing part is the type definition in the modify statement. With MODIFY you redefine the column, thus you need to give the new type as well. But in case you only modify that it can be null, no data will be lost.
Create referenced table and filling it :
mysql> -- Creating referenced table
mysql> create table `tUser` (
-> `id` int auto_increment not null,
-> `name` varchar(16),
-> primary key (`id`)
-> );
Query OK, 0 rows affected (0.07 sec)
mysql> -- Filling and checking referenced table
mysql> insert into `tUser` (`name`) values ("Jane"), ("John");
Query OK, 2 rows affected (0.04 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from `tUser`;
+----+------+
| id | name |
+----+------+
| 1 | Jane |
| 2 | John |
+----+------+
2 rows in set (0.07 sec)
mysql> -- Creating referencing table
mysql> create table `tHoliday` (
-> `id` int auto_increment not null,
-> `userId` int,
-> `date` date,
-> primary key (`id`),
-> foreign key (`userId`) references `tUser` (`id`)
-> );
Query OK, 0 rows affected (0.14 sec)
mysql> -- Filling and checking referencing table
mysql> insert into `tHoliday` (`userId`, `date`) values
-> (1, "2014-11-10"),
-> (1, "2014-11-13"),
-> (2, "2014-10-10"),
-> (2, "2014-12-10");
Query OK, 4 rows affected (0.08 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from `tHoliday`;
+----+--------+------------+
| id | userId | date |
+----+--------+------------+
| 1 | 1 | 2014-11-10 |
| 2 | 1 | 2014-11-13 |
| 3 | 2 | 2014-10-10 |
| 4 | 2 | 2014-12-10 |
+----+--------+------------+
4 rows in set (0.05 sec)
mysql> -- Updating foreign key column to allow NULL
mysql> alter table `tHoliday` modify `userId` int null;
Query OK, 0 rows affected (0.08 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> -- Inserting line without foreign key
mysql> insert into `tHoliday` (`date`) values ("2014-11-15");
Query OK, 1 row affected (0.06 sec)
mysql> select * from `tHoliday`;
+----+--------+------------+
| id | userId | date |
+----+--------+------------+
| 1 | 1 | 2014-11-10 |
| 2 | 1 | 2014-11-13 |
| 3 | 2 | 2014-10-10 |
| 4 | 2 | 2014-12-10 |
| 5 | NULL | 2014-11-15 |
+----+--------+------------+
5 rows in set (0.03 sec)
I have a mySQL (InnoDB) table:
belegID int NOT_NULL PRIMARY_KEY AUTO_INCREMENT,
docNum int NOT_NULL,
docYear date NOT_NULL,
.... -- more columns
I need the following relations:
belegID is the primary key (unique ID).
docNum is also a (unique) ID but related to the year. Each year starts by 1.
How can I solve this on mySQL side and how can I get the next docNum (ID related to the year)?
Thank you in advance.
You can use triggers to resolve your issue. Here is simple example (don't forget to rename schema and table if you'll try to use that):
DELIMITER //
CREATE TRIGGER fillDocNumber BEFORE INSERT ON test.t
FOR EACH ROW
BEGIN
SET #maxNum = (SELECT MAX(docNum) FROM test.t WHERE YEAR(docYear)=YEAR(NEW.docYear));
IF #maxNum IS NULL THEN
SET NEW.docNum=1;
ELSE
SET NEW.docNum=#maxNum+1;
END IF;
END;//
DELIMITER ;
Let's assume we have table:
CREATE TABLE `t` (
`belegID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`docNum` int(11) unsigned DEFAULT NULL,
`docYear` date NOT NULL,
PRIMARY KEY (`belegID`)
) ENGINE=InnoDB;
After creating our trigger we'll populate it with some data:
mysql> insert into t (docYear) values ('2013-04-06');
Query OK, 1 row affected (0.13 sec)
mysql> insert into t (docYear) values ('2012-02-18');
Query OK, 1 row affected (0.05 sec)
mysql> insert into t (docYear) values ('2013-12-11');
Query OK, 1 row affected (0.02 sec)
mysql> insert into t (docYear) values ('2014-10-30');
Query OK, 1 row affected (0.07 sec)
mysql> insert into t (docYear) values ('2014-01-03');
Query OK, 1 row affected (0.06 sec)
and now it's our result:
mysql> select * from t;
+---------+--------+------------+
| belegID | docNum | docYear |
+---------+--------+------------+
| 1 | 1 | 2013-04-06 |
| 2 | 1 | 2012-02-18 |
| 3 | 2 | 2013-12-11 |
| 4 | 1 | 2014-10-30 |
| 5 | 2 | 2014-01-03 |
+---------+--------+------------+
5 rows in set (0.00 sec)
Quite as expected.
Hint: rename field docYear, it's confusing. Correct name would be docDate (or store year in it and document's date in separate field - in fact, that will increase performance since then you'll be able to create index by it and get rid of YEAR() function in calculating MAX within trigger - and so index will be used).