When to CREATE TABLE AS SELECT versus CREATE TABLE LIKE? - mysql

I can "copy" a table using:
CREATE TABLE copy LIKE original_table
and
CREATE TABLE copy as select * from original_table
In the latter case only the data are copied but not e.g primary keys etc.
So I was wondering when would I prefer using a select as?

These do different things. CREATE TABLE LIKE creates an empty table with the same structure as the original table.
CREATE TABLE AS SELECT inserts the data into the new table. The resulting table is not empty. In addition, CREATE TABLE AS SELECT is often used with more complicated queries, to generate temporary tables. There is no "original" table in this case. The results of the query are just captured as a table.
EDIT:
The "standard" way to do backup is to use . . . . backup at the database level. This backs up all objects in the database. Backing up multiple tables is important, for instance, to maintain relational integrity among the objects.
If you just want a real copy of a table, first do a create table like and then insert into. However, this can pose a challenge with auto_increment fields. You will probably want to drop the auto_increment property on the column so you can populate such columns.

The second form is often used when the new table is not an exact copy of the old table, but contains only selected columns or columns that result from a join.

"Create Table as Select..." are most likely used when you have complex select
e.g:
create table t2 as select * from t1 where x1=7 and y1 <>2 from t1;
Now, apparently you should use Create Like if you don't need such complex selects. You can change the PI in this syntax also.

Related

MySQL update table dynamically

I wonder if there is a way to have an SQL table update itself dynamically.
I have table1 and table2 and I need to create a table3 using UNION and WHERE both tables ID column (PK) match but the issue is that I do not want to always create the same table3 instead if I add a record to the tables , let it appear automatically appear in table 3..
Any advise how it is done if possible or where should I look into?
Thanks
Table3 shouldn't be a table, it should be a view.
From the perspective of any given SELECT query and any consuming application looking at the data, a view can be treated like any other table. The fact that it's not a table is entirely transparent in those cases.
What a view does is compile and store a query which examines other tables, and presents the results of that query in a table structure. So any time you select from the view, you're dynamically selecting from the current state of the tables it examines.

SQL Entry's Duped

I messed up when trying to create a test Database and accidently duplicated everything inside of a certain table. Basically there is now 2 of every entry there was once before. Is there a simple way to fix this? (Using InnoDB tables)
Yet another good reason to use auto incrementing primary keys. That way, the rows wouldn't be total duplicates.
Probably the fastest way is to copy the data into another table, truncate the first table, and re-insert it:
create temporary table tmp as
select distinct *
from test;
truncate table test;
insert into test
select *
from tmp;
As a little note: in almost all cases, I recommend using the complete column list on an insert statement. This is the one case where it is optional. After all, you are putting all the columns in another table and just putting them back a statement later.

mySQL: duplicating multiple records via temporary table, how to preserve autoincrement index?

I wish to duplicate a selection of records in a mySQL table.
The pk of the table is an autoincremented int.
I want to do this with one set of mysql queries (for performance reasons).
It seems like the fastest way to do this is to put the results of the selection into a temporary table,
make any changes needed, and reinsert the records back to the original table, like this:
CREATE TEMPORARY TABLE temp1234 ENGINE=MEMORY SELECT * FROM a_table WHERE column='my selection';
# do updates in temp1234; (altering FK's mainly)
INSERT INTO a_table SELECT * FROM temp1234;
But when I try to do this i get an error for duplicate PKs.
Now, I realise that I could alter the INSERT with SELECT query to exclude the pk/ID column, but as I am proceduraly generating these queries across multiple tables for a large data copying function, i want to avoid having to supply column names.
What is the best way around this problem?

How can I store the output of a query into a temporary table and use the table in a new query?

I have a MySQL query which uses 3 tables with 2 inner joins. Then, I have to find the maximum of a group from this query output. Combining them both is beyond me. Can I break down the problem by storing the output of the first complicated query into some sort of temporary table, give it a name and then use this table in a new query? This will make the code more manageable. Thank you for your help.
This is very straightforward:
CREATE TEMPORARY TABLE tempname AS (
SELECT whatever, whatever
FROM rawtable
JOIN othertable ON this = that
)
The temporary table will vanish when your connection closes. A temp table contains the data that was captured at the time it was created.
You can also create a view, like so.
CREATE VIEW viewname AS (
SELECT whatever, whatever
FROM rawtable
JOIN othertable ON this = that
)
Views are permanent objects (they don't vanish when your connection closes) but they retrieve data from the underlying tables at the time you invoke them.

Create as Select and add an extra column

I want to create a MySQL table as a copy of another table like this:
CREATE TABLE new_tbl SELECT * FROM orig_tbl;
The twist is that I want, if possible, to add at the time of creation another empty column, that will be populated at a later time.
I know that I can just create it as above and use ALTER TABLE afterwards, but my thinking is that, given a large amount of data, the ALTER is gonna take a long time (please contradict me if this is wrong), that can be saved if what I want is possible.
So, say I want an extra extra_col - varchar(64), what would my original query be?
Thanks.
As documented under CREATE TABLE ... SELECT Syntax:
You can create one table from another by adding a SELECT statement at the end of the CREATE TABLE statement:
CREATE TABLE new_tbl SELECT * FROM orig_tbl;
MySQL creates new columns for all elements in the SELECT.
[ deletia ]
Notice that the columns from the SELECT statement are appended to the right side of the table, not overlapped onto it.
[ deletia ]
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.
Therefore:
CREATE TABLE new_tbl (
extra_col VARCHAR(64)
) SELECT * FROM orig_tbl
#user1703809 You have a workaround if you want to place the added column at the end by placing the extra column in the Select statement as :
CREATE |TEMPORARY| TABLE IF NOT EXISTS new_tbl
SELECT *, REPEAT('-',64) extra_col
FROM orig_tbl;
This will create your new table with an added column "extra_col" - varchar(64). Furthermore, you may create the table as temporary if it suits you, and if you just want to create an empty table for further use, just add a "LIMIT 0" at the end of the statement.
Furthermore, this way, you may add a column in any position of the field list at the Select statement.
It's been sometime since you asked the question but I'm still hoping to be of some help.