I have registration table with different fields. I have thousands of records in that table. But now I want to add one column called 'gender' to that table. So How Do I insert values for previous thousands of records in the table??
Either use a default value for your new column or add a value afterwards with an update statement.
So either
alter table your_table
add column gender char(1) default '-'
or
update your_table
set gender = '-'
where gender is null
Either way setting a gender to a default value is rather bad since this is a boolean condition which is wrong setting it for all records to a certain value.
DEMO
Adding column:
alter table table_name add column gender char(1)
updating all values:
update table_name set gender = 'M'
Related
I have two tables that have a huge list of columns. They are both the same structure, but different data. However, both tables have an index/auto-increment column that might be similar. Is there an easy way to run a command like this:
insert into table1 (select * from table2);
and have the insert ignore the auto-increment column from table 2? To avoid an error if there's a similar-value in the index column of tables 1 and 2? I want to copy everything over, and have new auto-increments for the table 2 data in table 1.
Alternatively, I don't care what the values are of the auto-increment index. If there was a way to merge the two tables and then re-generate unique AI columns that would also work.
I am aware I could get around this by specifying each field individually in both tables and leaving out the auto-increment column. I'm just wondering if there is an easier way to do this? If there isn't, is there an easy way of generating the field list/statement?
Here is the most efficient way I know of right now. Assuming the A.I. index is called "recno"
ALTER TABLE table1 DROP COLUMN recid;
ALTER TABLE table2 DROP COLUMN recid;
insert into table1 (select * from table2);
ALTER TABLE table1 ADD `recid` INT NOT NULL AUTO_INCREMENT [AFTER `column`], ADD PRIMARY KEY (`recid`);
ALTER TABLE table2 ADD `recid` INT NOT NULL AUTO_INCREMENT [AFTER `column`], ADD PRIMARY KEY (`recid`);
There's not really a way to do that. The * in the SELECT list means "all columns" in ordinal position. There's not exception for columns that meet specified criteria.
The same is true for an omitted list of columns that we're inserting into... it's all of the columns.
The most efficient way (in terms of database resources) to accomplish the specified goal is to list the columns, and omit the auto_increment column from the list.
INSERT INTO t (b,c,d,e) SELECT b,c,d,e FROM s ;
We can get a list of columns names for a table from information_schema.columns...
For example, to get a list of the column names in table2:
SELECT c.column_name
FROM information_schema.columns c
WHERE c.table_schema = 'mydatabase'
AND c.table_name = 'table2'
ORDER
BY c.ordinal_position
To exclude the auto_increment column from the list, we can add a WHERE clause, that excludes that column by it's name
WHERE c.column_name NOT IN ('my_autoincrement_column_name')
or we can check for 'auto_increment' occurring the EXTRA column
WHERE c.extra NOT LIKE '%auto_increment%'
To get a column list for each of the two tables, excluding the auto_increment columns, we could do something like this:
SET group_concat_max_len = 16777216 ;
SELECT GROUP_CONCAT( CONCAT('`',c.column_name,'`')
ORDER BY c.ordinal_position
SEPARATOR ','
) AS `-- column_list`
FROM information_schema.columns c
WHERE c.table_schema = 'mydatabase'
AND c.table_name IN ('table1','table2')
AND c.extra NOT LIKE '%auto_increment%'
GROUP
BY c.table_schema
, c.table_name
ORDER
BY c.table_schema
, c.table_name
EDIT
I'd take the column lists, and build a SQL query.
If we're going to make changes to table2 (dropping the auto_increment column as suggested in another answer to this question), and if we don't need to preserve the values in the column, the easiest change would be to just set all of the values in that column to NULL.
No need to modify table1.
We can remove the auto_increment attribute (and the NOT NULL constraint if that's specified) from the column in table2, and set the column to null. Assuming ai is the name of the auto_increment column, and assuming it's declared to be INT UNSIGNED datatype, we can do:
ALTER TABLE `table2` CHANGE `ai` `ai` INT UNSIGNED COMMENT '' ;
UPDATE `table2` SET `ai` = NULL ;
Then we can do an INSERT INTO table1 SELECT * FROM table2
And then add back the auto_increment attribute to the column in table2.
This approach is more expensive (in terms of the database resources) than a single INSERT ... SELECT.
Generating a column list is an extra step, but the resulting operation would be much more efficient. We could generate a list of columns from just the source table, and then replace the column name with literal NULL value...
INSERT INTO t SELECT NULL,b,c,d FROM s;
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
Need assistance on the following. How can I copy data from one SQL column table to another sql column table?
I have the following tables
dbo.Thecat62 and dbo.thecase6
inside dbo.Thecat62 , I need to copy the column Work_Order_Job_Start_Date values to dbo.thecase6 column Job_Start_Date. Currently there are null value in the Job_Start_Date column in dbo.thecase6.
I have tried using the following command
INSERT INTO dbo.thecase6 (Job_Start_Date)
SELECT Work_Order_Job_Start_Date
FROM dbo.thecat62
but received the error Cannot insert the value NULL into column 'CaseNo', table 'Therefore.dbo.TheCase6'; column does not allow nulls. INSERT fails.
The statement has been terminated.
Any help will be great!
Thanks!
Because on this table Therefore.dbo.TheCase6 for CaseNo you have specify Not NULL Constraints
something like this
CaseNo int NOT NULL
But you did not select the CaseNo column from the dbo.thecat62 table, so you are explicitly trying to insert nulls into a non-nullable column.
You just need to select the CaseNo column, as well, presuming it does not contain any nulls in teh source table.
INSERT INTO dbo.thecase6 (Job_Start_Date,CaseNo)
SELECT Work_Order_Job_Start_Date,CaseNo FROM dbo.thecat62
The error says it has a column CaseNo which doesn't allow NULL.
Cannot insert the value NULL into column 'CaseNo', table 'Therefore.dbo.TheCase6';
You are inserting rows in the new table which will have just 1 column filled and rest of the columns will be empty
Either
Alter the table in which you are inserting the data and allow the column to allow null values.
Or
if you don't want to allow null values, update the null values to some default values.
Hi help in this case i need to insert two columns in a table one column has to be default value as 'Other'(Please don't suggest to put Other as default value) and other column should get inserted from different table.
This is my sample code please suggest necessary change:
INSERT INTO table1 (`ID`,`specialty`)
SELECT `ID`,`here i need to put default value as other` from table2 a WHERE
Id IS NOT NULL
Do you mean this?
INSERT INTO table1 (ID,specialty)
SELECT ID, 'Other'
FROM table2
WHERE ID IS NOT NULL
Can I, and, if I can, how can I set the default value of a field in a MySQL table to the value of another field?
Thing is: I have data, and each data object has its ID in the table. But, I would like the possibility to rearrange the data, changing their sorting index, without altering their ID. Thus, the field sort_num should by default be set to the value given to the auto-incremented indexed field ID.
Thanks in advance!
I see two possible solutions for this:
1. Possibility:
You use a function to simply ignore sort_num if it is not set:
`SELECT * FROM mytable ORDER BY coalesce(sort_num, id)`
coalesce() returns the first non-null value, therefore you would insert values for sort_num if you really need to reorder items.
2. Possibility:
You write a trigger, which automatically sets the value if it is not set in the insert statement:
DELIMITER //
CREATE TRIGGER sort_num_trigger
BEFORE INSERT ON mytable
FOR EACH ROW BEGIN
DECLARE auto_inc INT;
IF (NEW.sort_num is null) THEN
-- determine next auto_increment value
SELECT AUTO_INCREMENT INTO auto_inc FROM information_schema.TABLES
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME = 'mytable';
-- and set the sort value to the same as the PK
SET NEW.sort_num = auto_inc;
END IF;
END
//
(inspired by this comment)
However, this might run into parallelization issues (multiple queries inserting at the same time)
Its a bad idea to have an auto-increment column rearranged, hence better idea would be
Add a column sort_num to the table
ALTER TABLE data ADD sort_num column-definition; (column definition same as ID)
UPDATE data SET sort_num = ID
Now play with sort_num column as it has no effect on column ID