As of MySQL 3.23, you can create one table from another by
adding a SELECT statement at the
end of the CREATE TABLE
statement:
CREATE TABLEnew_tbl[AS] SELECT * FROMorig_tbl;
MySQL creates new columns for all elements in the
SELECT. For example:
mysql>CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,->PRIMARY KEY (a), KEY(b))->TYPE=MyISAM SELECT b,c FROM test2;
This creates a MyISAM table with three
columns, a, b, and
c. Notice that the columns from the
SELECT statement are appended to
the right side of the table, not overlapped onto it. Take the
following example:
mysql>SELECT * FROM foo;+---+ | n | +---+ | 1 | +---+ mysql>CREATE TABLE bar (m INT) SELECT n FROM foo;Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql>SELECT * FROM bar;+------+---+ | m | n | +------+---+ | NULL | 1 | +------+---+ 1 row in set (0.00 sec)
For each row in table foo, a row is inserted
in bar with the values from
foo and default values for the new columns.
In a table resulting from
CREATE TABLE ...
SELECT, columns named only in the
CREATE TABLE part come first.
Columns named in both parts or only in the
SELECT part come after that. The
data type of SELECT columns can
be overridden by also specifying the column in the
CREATE TABLE part.
If any errors occur while copying the data to the table, it is automatically dropped and not created.
You can precede the SELECT by
IGNORE or
REPLACE to indicate how to handle
rows that duplicate unique key values. With
IGNORE, new rows that duplicate an existing
row on a unique key value are discarded. With
REPLACE, new rows replace rows
that have the same unique key value. If neither
IGNORE nor
REPLACE is specified, duplicate
unique key values result in an error.
CREATE TABLE ...
SELECT does not automatically create any indexes for
you. This is done intentionally to make the statement as
flexible as possible. If you want to have indexes in the created
table, you should specify these before the
SELECT statement:
mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;
Some conversion of data types might occur. For example, the
AUTO_INCREMENT attribute is not preserved,
and VARCHAR columns can become
CHAR columns. Retrained
attributes are NULL (or NOT
NULL) and, for those columns that have them,
CHARACTER SET, COLLATION,
COMMENT, and the DEFAULT
clause.
When creating a table with
CREATE
TABLE ... SELECT, make sure to alias any function
calls or expressions in the query. If you do not, the
CREATE statement might fail or result in
undesirable column names.
CREATE TABLE artists_and_works SELECT artist.name, COUNT(work.artist_id) AS number_of_works FROM artist LEFT JOIN work ON artist.id = work.artist_id GROUP BY artist.id;
As of MySQL 4.1, you can explicitly specify the data type for a generated column:
CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;
For CREATE TABLE
... SELECT, if IF NOT EXISTS is
given and the destination table already exists, MySQL handles
the statement as follows:
The table definition given in the
CREATE TABLE part is ignored.
No error occurs, even if the definition does not match that
of the existing table. MySQL attempts to insert the rows
from the SELECT part anyway.
If there is a mismatch between the number of columns in the
table and the number of columns produced by the
SELECT part, the selected
values are assigned to the rightmost columns. For example,
if the table contains n columns
and the SELECT produces
m columns, where
m <
n, the selected values are
assigned to the m rightmost
columns in the table. Each of the initial
n –
m columns is assigned its default
value, either that specified explicitly in the column
definition or the implicit column data type default if the
definition contains no default. If the
SELECT part produces too many
columns (m >
n), an error occurs.
The following example illustrates IF NOT
EXISTS handling:
mysql>CREATE TABLE t1 (i1 INT DEFAULT 0, i2 INT, i3 INT, i4 INT);Query OK, 0 rows affected (0.05 sec) mysql>CREATE TABLE IF NOT EXISTS t1 (c1 CHAR(10)) SELECT 1, 2;Query OK, 1 row affected, 1 warning (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql>SELECT * FROM t1;+------+------+------+------+ | i1 | i2 | i3 | i4 | +------+------+------+------+ | 0 | NULL | 1 | 2 | +------+------+------+------+ 1 row in set (0.00 sec)
To ensure that the update log or binary log can be used to
re-create the original tables, MySQL does not permit concurrent
inserts for CREATE
TABLE ... SELECT statements.

User Comments
2 Further examples of type casting wen using a function (INT > DECIMAL(14,4) and FLOAT > DOUBLE):
1 row in set (0.00 sec)mysql> CREATE TABLE t1 (id INT);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO t1 VALUES (1),(3),(1);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> CREATE TABLE t2 SELECT AVG(id) FROM t1;
Query OK, 1 row affected, 1 warning (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 1
mysql> SHOW WARNINGS;
mysql> SHOW CREATE TABLE t2\G
*************************** 1. row ***************************
Table: t2
Create Table: CREATE TABLE `t2` (
`AVG(id)` decimal(14,4) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> SELECT * FROM t2\G
*************************** 1. row ***************************
AVG(id): 1.6667
1 row in set (0.00 sec)
mysql> DROP TABLE t1,t2;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t1 (id FLOAT);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO t1 VALUES (1),(3),(1);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> CREATE TABLE t2 SELECT AVG(id) FROM t1;
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> SHOW CREATE TABLE t2\G
*************************** 1. row ***************************
Table: t2
Create Table: CREATE TABLE `t2` (
`AVG(id)` double DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> SELECT * FROM t2\G
*************************** 1. row ***************************
AVG(id): 1.6666666666666667
1 row in set (0.00 sec)
mysql> DROP TABLE t1,t2;
Query OK, 0 rows affected (0.00 sec)
Add your own comment.