Max of a coll in my sql - mysql

I want to make a register system, to record some values from html inputs in a Database, I use the following query:INSERT INTO Search (id, username, fname, lname, age, fullname) VALUES ('?', '$username', '$fname', '$lname', '$age', '$fullname');
But I don't know how to increment the id every time when submit a name:
see here
I want something like:
id
""""""""""""""""
1
max+1
new max+1

You don't; you make it an auto increment column ( https://dev.mysql.com/doc/refman/5.7/en/example-auto-increment.html ) and then you don't specify it in the insert statement, and mysql will calculate the next value to put in automatically

When creating your table, you should specify the id column to AUTO_INCREMENT like so:
id INTEGER NOT NULL AUTO_INCREMENT
you can alter your table at this point.
You should definitely not do this by hand IMO.
You should also consider declaring it a PRIMARY KEY.

Run the following:
ALTER TABLE Search
CHANGE COLUMN id id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
ADD PRIMARY KEY (id);
or execute two queries:
SET #max = 0;
INSERT INTO Search
(id, username, fname, lname, age, fullname)
VALUES
(#max:=#max+1, '$username', '$fname', '$lname', '$age', '$fullname');

Related

How to use SELECT MAX inside an INSERT statement in MySQL?

Short Version:
How can I get the maximum value of a column and use the result when adding a row with INSERT INTO statement?
Long Version:
I have read the question: How to use 'select ' in MySQL 'insert' statement and tried to follow the instructions for its answers. This is my query:
INSERT INTO employee (id, name, state, supervisorId) SELECT MAX(id)+1, 'Dan', state, supervisorId FROM employee WHERE name='Chris';
But I get this error:
ERROR: 1062: Duplicate entry '7' for key 'PRIMARY'
The reason is that I have another row whose id is 7. Consequently,
MAX(id)
doesn't return the actual maximum value, but a value equal to id of the row containing 'Chris' which is 6.
What am I doing wrong?
You can fix it by replacing this:
MAX(id)+1
with this select query:
(SELECT MAX(id)+1 FROM employee)
Here's the complete query:
INSERT INTO employee (id, name, state, supervisorId) SELECT (SELECT MAX(id)+1 FROM employee), 'Dan', state, supervisorId FROM employee WHERE name='Chris';
Update:
Although this answer solves the general question about getting the SELECT MAX inside an INSERT query, as #RaymondNijland suggested, it's better to make the most of MySQL auto_increment functionalities. To do so:
1) Make your primary key column, auto incremented:
ALTER TABLE employee MODIFY COLUMN id INT NOT NULL AUTO_INCREMENT;
2) Remove the id from your insert query:
INSERT INTO employee (name, state, supervisorId) SELECT 'Dan', state, supervisorId FROM employee WHERE name='Chris';
Using manual increment on SQL queries can lead to race conditions.
You should have the AI (auto increment) constraint when you create your table PK (Primary Key).
CREATE TABLE table_name
(
table_id int NOT NULL PRIMARY KEY AUTO INCREMENT,
....
);
If you absolutely have to use manual increment, use SELECT statement.

Two autoincrements columns or autoincrement and same value in other column

I need two columns in table that would have same value on insert. Is there any way to do it from database side?
So you want to let one column use the auto_increment feature, but make another column in the same table also have the same value?
I can't think of a reason you would need this feature. Perhaps you could explain what you're trying to accomplish, and I can suggest a different solution?
A trigger won't work for this. It's a chicken-and-egg problem:
You can't change any column's value in an AFTER trigger.
But the auto-increment value isn't set yet when a BEFORE trigger executes.
It also won't work to use a MySQL 5.7 GENERATED column:
CREATE TABLE MyTable (
id INT AUTO_INCREMENT PRIMARY KEY,
why_would_you_want_this INT GENERATED ALWAYS AS (id)
);
ERROR 3109 (HY000): Generated column 'why_would_you_want_this'
cannot refer to auto-increment column.
You can't do it in a single SQL statement. You have to INSERT the row, and then immediately do an UPDATE to set your second column to the same value.
CREATE TABLE MyTable (
id INT AUTO_INCREMENT PRIMARY KEY,
why_would_you_want_this INT
);
INSERT INTO MyTable () VALUES ();
UPDATE MyTable SET why_would_you_want_this = LAST_INSERT_ID()
WHERE id = LAST_INSERT_ID();
You could alternatively generate the ID value using some other mechanism besides AUTO_INCREMENT (for example a Memcached incrementing key). Then you could insert the new value in both columns:
INSERT INTO MyTable (id, why_would_you_want_this) VALUES ($gen_id, $gen_id);
Define a before or after insert trigger and assign the value of the 2nd field in the trigger.
If the 1st field is an auto increment column, then you need to use an after insert trigger. If your application assigns value to the 1st field, then you can use a before insert trigger.
However, I would no necessarily duplicate the value on insert. You can leave the 2nd field as null on insert, which would mean that its value is the same as the 1st field's. The only drawback of this approach is that it may be more difficult to create joins on the 2nd field.
You can do this in one query by using the primary key (assumed to be id) and setting your column (assumed to be columnName):
"INSERT INTO tableName SET `columnName` = (SELECT MAX(x.id) FROM tableName x)+1"
This will not work if you have deleted the most recent primary key row however. To get past this, you can insert into the id as well:
"INSERT INTO tableName SET `columnName` = (SELECT MAX(x.id) FROM tableName x)+1, `id`= (SELECT MAX(x.id) FROM tableName x)+1"
However, this solution has the downside (or upside depending on the case) of reusing primary key values that have already been deleted.
suggested way:
To use the actual auto_increment value, you can do this:
"INSERT INTO tableName SET `columnName` = (SELECT `AUTO_INCREMENT` FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME = 'table_name')"
Sources that helped me solve this: Prashant Pimpale's answer

How to insert mysql like this?another field need auto_increment id to split

In my database mysql table, there is one field ,It was split by auto_increment id and other str , For example:
insert into tableName (id, title, link, keyword) values (NULL, 'Title', 'http://www.domain.com/id', 'keyword');
How could that work?
http://www.domain.com/id, this 'id' is the auto_increment id.
Unfortunately, you can't make it automatically since mysql for auto increment fields, doesn't know beforehand the inserted id. You could update the row after it is inserted:
INSERT INTO tableName (title, keyword) VALUES('Title', 'keyword');
UPDATE tableName
SET link = CONCAT('http://www.domain.com/', LAST_INSERT_ID())
WHERE id = LAST_INSERT_ID();
If id is auto_increment you don't need to set it on insert, just like this:
insert into tableName (title, link, keyword) values ('Title', 'http://www.domain.com/id', 'keyword');
In general if it auto incremented field, it can be your primary key and add other indexes as you need.

using mysql to auto populate a sort order

I have a table called t_home_feature with the following columns: id, type, sort_order. I then executed the following MySQL statement:
INSERT INTO t_home_feature (SELECT news_id, 'news', ( SELECT max(sort_order) + 1 FROM t_home_feature ) FROM t_news )
I then did a SELECT * FROM t_home_feature but the sort_order for all rows has a value that is equal to the number of rows in t_home_feature prior to the insert statement, instead of a value like previous row + 1.
How can I modify my insert query to achieve a previous row + 1 output?
You could turn the sort_order into an auto_increment field, which means the database will automatically increment it and you need not refer to it in your insert. This has to be a key, but not a primary key. For example, here's an example from:
http://forums.mysql.com/read.php?22,264498,264967#msg-264967
There the link has an example of a workaround:
create table ai (
id int auto_increment not null,
xx varchar(9),
key(id),
primary key (xx));
You may have to do something fancy with local variables. Perhaps something like this:
SELECT COUNT(1) INTO #maxval FROM t_home_feature;
INSERT INTO t_home_feature
SELECT news_id, 'news', #maxval:=#maxval+1 FROM t_news ;
No need to any auto increment values from tables.
I have done things like this when answering questions before. Here are four(4) examples of questions I answered in the DBA StackExchange using local variables:
https://dba.stackexchange.com/questions/29007/update-ranking-on-table/29009#29009
https://dba.stackexchange.com/questions/29016/selecting-without-repititions/29018#29018
https://dba.stackexchange.com/questions/18987/update-rank-on-a-large-table/18990#18990
https://dba.stackexchange.com/questions/10251/whats-wrong-with-this-update-rank-query10320#10320

MySQL: Creating a table with auto increment and concatenating the values generated with the values of a different column of the same table

I want to create a table employee with id,name,dept,username attributes.
The id column values are auto_increment. I want to concatenate the values of id with dept to generate the username.
Following is the query that I wrote:
create table employee emp_id MEDIUMINT NOT NULL AUTO_INCREMENT, name char(30) NOT NULL, dept char(6)NOT NULL, username varchar NOT NULL PRIMARY KEY(emp_id);
How to insert values into this table properly? Please help.
If your usernames will always be the concatenation of id and dept, you don't need to create a separate column for it, you can just select it using the MySQL CONCAT function, like this:
SELECT id, name, dept, CONCAT(id, '-', dept) AS username FROM employee
This will return results for username like 13-sales.
If you want to actually store the username (maybe because you want the ability to customize it later), you'll have to first insert the row to get the id, and then update the row setting the username to the concatenated id and dept.
You can use null on MySQL for auto traslate as the last id:
INSER INTO employee (name, dept) VALUES (?,?);
UPDATE employee SET username = concant(emp_id,dept) WHERE emp_id = NULL;