Difference between Select Into and Insert Into from old table? - sql

What is difference between these in terms of constraints *keys* etc.
Select Into Statement
SELECT column1, column2, someInt, someVarChar
INTO ItemBack1
FROM table2
WHERE table2.ID = 7
Insert Into Statement
INSERT INTO table1 ( column1, column2, someInt, someVarChar )
SELECT table2.column1, table2.column2,
FROM table2
WHERE table2.ID = 7
and also
Create table ramm as select * from rammayan
Edit 1:
Database SQL Server 2008

I'm going to assume MySQL here.
The first two are identical, as the documentation states.
The third statement allows for both table creation and population, though your syntax is wrong up there; look at the right syntax for more info.
Update
It's SQL Server =p
SELECT column1, column2, someInt, someVarChar
INTO ItemBack1
FROM table2
WHERE table2.ID = 7
The first statement will automatically create the ItemBack1 table, based on table2.
INSERT INTO table1 ( column1, column2, someInt, someVarChar )
SELECT table2.column1, table2.column2,
FROM table2
WHERE table2.ID = 7
The second second statement requires that table1 already exists.
See also: http://blog.sqlauthority.com/2007/08/15/sql-server-insert-data-from-one-table-to-another-table-insert-into-select-select-into-table/
If there's any difference in constraints, it would be because the second statement depends on what you have already created (and if the table is populated, etc.).
Btw, the third statement is Oracle(tm) and is the same as the first statement.

There are some very important differences between SELECT INTO and INSERT.
First, for the INSERT you need to pre-define the destination table. SELECT INTO creates the table as part of the statement.
Second, as a result of the first condition, you can get type conversion errors on the load into the table using INSERT. This cannot happen with a SELECT INTO (although the underlying query could produce an error).
Third, with a SELECT INTO you need to give all your columns names. With an INSERT, you do not need to give them names.
Fourth, SELECT INTO locks some of the metadata during the processing. This means that other queries on the database may be locked out of accessing tables. For instance, you cannot run two SELECT INTO statements at the same time on the same database, because of this locking.
Fifth, on a very large insert, you can sometimes see progress with INSERT but not with SELECT INTO. At least, this is my experience.
When I have a complicated query and I want to put the data into a table, I often use:
SELECT top 0 *
INTO <table>
FROM <query>
INSERT INTO <table>
SELECT * FROM <query>

Select Into ->Creates the table on the fly upon select execution
while
Insert Into ->Presumes that the Table DB already exist
lastly
Create, simply creates the table from the return result of the query

I don't really understand your question. Let's try:
The 1st one selects the value of the columns "someVarChar" into a variable called "ItemBack1". Depending on your SQL-Server (mysql/oracle/mssql/etc.) you can now do some logic with this var.
The 2nd one inserts the result of
SELECT table2.column1, table2.column2, 8, 'some string etc.'
FROM table2
WHERE table2.ID = 7
into the table1 (Copy)
And the 3rd creates a new table "ramm" as a copy of the table "rammayan"

Generally speaking
Each one has its own particularities, one creates a temporary table, other uses a previously existing table and the third one creates a new table with exact same estructure and formatting
SELECT…INTO creates a new table in the default filegroup and inserts the resulting rows from the query into it
INSERT INTO: fills an already existing table
INSERT...INTO
The third option is known as CTAS (Create Table As Select) do a search and you will get tons of usefull links. Basically it creates a table, not a temporary one, with the structure and types used on the SELECT statement.
I wanted to add some more links but as I'm a new user I'm only allowed to post 2 links to prevent spam.

INSERT INTO SELECT inserts into an existing table.
SELECT INTO creates a new table and puts the data in it.
All of the columns in the query must be named so each of the columns in the table will have a name. This is the most common mistake I see for this command.
The data type and nullability come from the source query.
If one of the source columns is an identity column and meets certain conditions (no JOINs in the query for example) then the column in the new table will also be an identity.
INSERT INTO SELECT
CREATE TABLE ExistingTableName1 (ColumnName VARCHAR(255));
GO
INSERT
INTO ExistingTableName1
SELECT ColumnaName
FROM ExistingTableName2;
GO
SELECT INTO INSERT
SELECT ColumnName INTO NewTableName
FROM ExistingTableName1;
GO

The SQL SELECT INTO Statement
The SELECT INTO statement copies data from one table into a new table.
SELECT INTO Syntax
SELECT column1, column2, column3, ...
INTO newtable [IN externaldb]
FROM oldtable
WHERE condition;
The new table will be created with the column-names and types as defined in the old table. You can create new column names using the AS clause.
The SQL INSERT INTO SELECT Statement
The INSERT INTO SELECT statement copies data from one table and inserts it into another table.
INSERT INTO SELECT Syntax
INSERT INTO table2 (column1, column2, column3, ...)
SELECT column1, column2, column3, ...
FROM table1
WHERE condition;
INSERT INTO SELECT requires that data types in source and target tables match
The existing records in the target table are unaffected

Related

ORA-00947 - not enough values: Occurs in one server but not another

I am work on a project which has to add one column to the exist table.
It is like this:
The OLD TBL Layout
OldTbl(
column1 number(1) not null,
column2 number(1) not null
);
SQL TO Create the New TBL
create table NewTbl(
column1 number(1) not null,
column2 number(1) not null,
**column3 number(1)**
);
When I try to insert the data by the SQL below,
on one oracle server,it was successful executed,
but on another oracle server, I got "ORA-00947 error: not enough values"
insert into NewTbl select
column1,
column2
from OldTbl;
Is there any oracle option may cause this kind of difference in oracle?
ORA-00947: not enough values
this is the error you received, which means, your table actually has more number of columns than you specified in the INSERT.
Perhaps, you didn't add the column in either of the servers.
There is also a different syntax for INSERT, which is more readable. Here, you mention the column names as well. So, when such a SQL is issued, unless a NOT NULL column is missed out, the INSERT still work, having null updated in missed columns.
INSERT INTO TABLE1
(COLUMN1,
COLUMN2)
SELECT
COLUMN1,
COLUMN2
FROM
TABLE2
insert into NewTbl select
column1,
column2
from OldTbl;
The above query is wrong, because your new table has three columns, however, your select has only two columns listed. Had the number and the order of the columns been same, then you could have achieved it.
If the number of the columns, and the order of the columns are different, then you must list down the column names in the correct order explicitly.
I would prefer CTAS(create table as select) here, it would be faster than the insert.
CREATE TABLE new_tbl AS
SELECT column1, column2, 1 FROM old_tbl;
You could use NOLOGGING and PARALLEL to increase the performance.
CREATE TABLE new_tbl NOLOGGING PARALLEL 4 AS
SELECT column1, column2, 1 FROM old_tbl;
This will create the new table will 3 columns, the first two columns will have data from the old table, and the third column will have value as 1 for all rows. You could keep any value for the third column as per your choice. I kept it as 1 because you wanted the third column as data type NUMBER(1).

Save return values from INSERT...RETURNING into temp table (PostgreSQL)

I have a table table1 with columns id,value1 and value2.
Also I have a query
INSERT INTO table1(value1,value2) SELECT value3,value4 FROM table2 RETURNING id
that returns set of ids.
I want to store return values (these ids) in some temp table. Something like that:
INSERT INTO TEMP temp1 INSERT INTO table1(value1,value2) SELECT value3,value4 FROM table2 RETURNING id
How can I do it?
DBMS is PostgreSQL
with inserted as (
INSERT INTO table1 (value1,value2)
SELECT value3,value4
FROM table2
RETURNING id
)
insert into temp
select id
from inserted;
This requires Postgres 9.2 or later.
Two options.
If you need it just for one follow-up query, a with statement (see the horse's answer) is the easiest.
If you need it for more than one follow-up query, the other option is to not use insert ... returning, but rather create table as:
CREATE TEMPORARY TABLE foo AS
SELECT value3,value4 FROM table2
Caveats: if necessary, create the indexes you need on the table -- and analyze it if you do.

How to select data and insert those data using single sql?

I want to select some data using simple sql and insert those data into another table. Both table are same. Data types and column names all are same. Simply those are temporary table of masters table. Using single sql I want to insert those data into another table and in the where condition I check E_ID=? checking part. My another problem is sometime there may be any matching rows in the table. In that time is it may be out sql exception? Another problem is it may be multiple matching rows. That means one E_ID may have multiple rows. As a example in my attachment_master and attachments_temp table has multiple rows for one single ID. How do I solve those problems? I have another problem. My master table data can insert temp table using following code. But I want to change only one column and others are same data. Because I want to change temp table status column.
insert into dates_temp_table SELECT * FROM master_dates_table where e_id=?;
In here all data insert into my dates_temp_table. But I want to add all column data and change only dates_temp_table status column as "Modified". How should I change this code?
You could try this:
insert into table1 ( col1, col2, col3,.... )
SELECT col1, col2, col3, ....
FROM table2 where (you can check any condition here on table1 or table2 or mixed)
For more info have a look here and this similar question
Hope it may help you.
EDit : If I understand your requirement properly then this may be a helpful solution for you:
insert into table1 ( col-1, col-2, col-3,...., col-n, <Your modification col name here> )
SELECT col-1, col-2, col-3,...., col-n, 'modified'
FROM table2 where table1.e_id=<your id value here>
As per your comment in above other answer:
"I send my E_ID. I don't want to matching and get. I send my E_ID and
if that ID available I insert those data into my temp table and change
temp table status as 'Modified' and otherwise don't do anything."
As according to your above statements, If given e_id is there it will copy all the columns values to your table1 and will place a value 'modified' in the 'status' column of your table1
For more info look here
You can use merge statement if I understand your requirement correctly.
Documentation
As I do not have your table structure below is based on assumption, see whether this cater your requirement. I am assuming that e_id is primary key or change as per your table design.
MERGE INTO dates_temp_table trgt
USING (SELECT * FROM master_dates_table WHERE e_id=100) src
ON (trgt.prm_key = src.prm_key)
WHEN NOT MATCHED
THEN
INSERT (trgt.col, trgt.col2, trgt.status)
VALUES (src.col, src.col2, 'Modified');
More information and examples here
insert into tablename( column1, column2, column3,column4 ) SELECT column1,
column2, column3,column4 from anothertablename where tablename.ID=anothertablename.ID
IF multiple values are there then it will return the last result..If not you have narrow your search..

copy the tables after execution

I would like to create new table after executing that query
create table newTable as select * from oldTable
However, this does not appear to work. How do I get the new table after executing some queries?
The syntax in general is like:
CREATE TABLE new_table
AS (SELECT * FROM old_table);
For example:
CREATE TABLE suppliers
AS (SELECT id, address, city, state, zip
FROM companies
WHERE id > 1000);
Try removing the stars (*) and add the brackets.
Read here for more examples.
I am not sure what DBMS you are using or what errors you are getting, so I will try to answer for multiple systems.
If you are working with Oracle or PostgreSQL (there might be some other systems that this rule applies to), your syntax seems to be correct. Just make sure your new table doesn't exist yet - otherwise it's going to error out. In case if you are trying to insert into an existing table - which I don't think the case is, however - you can try something like -
INSERT INTO newTable SELECT * FROM oldTable
On the other hand, if you are working with T-SQL (SQL Server), you could SELECT INTO the new table. The new table will be created with the old table's schema.
You can read more about the INTO Clause at MSDN Library.
Your code should look like -
SELECT *
INTO newTable
FROM oldTable
And, specifying the column names and filters also works the similar way -
SELECT Column1, Column2, Column3, ...
INTO newTable
FROM oldTable
WHERE <Filter Condition>
Whatever the case is, you would get more help if you specify the details.
As You Said you want to copy the values into new table after execution
whether if you are running the stored procedure using cursor let the cursor shuld be closed then use query as follows
Select * into Table1 from Table2
if you want to copy selected colums go for
Select Coloumn1 ,column2,... into table1 from table 2 where ............

SQL insert into using Union should add only distinct values

So I have this temp table that has structure like:
col1 col2 col3 col3
intID1 intID2 intID3 bitAdd
I am doing a union of the values of this temp table with a select query and storing
it into the same temp table.The thing is col3 is not part of the union query I will
need it later on to update the table.
So I am doing like so:
Insert into #temptable
(
intID1,
intID2,
intID3
)
select intID1,intID2,intID3
From
#temptable
UNION
select intID1,intID2,intID3
From
Table A
Issue is that I want only the rows that are not already existing in the temp table to be added.Doing it this way will add a duplicate of the already existing row(since union will return one row)How do I insert only those rows not existing in the current temp table in my union query?
Use MERGE:
MERGE INTO #temptable tmp
USING (select intID1,intID2,intID3 From Table A) t
ON (tmp.intID1 = t.intID1 and tmp.intID2 = t.intID2 and tmp.intID3 = t.intID3)
WHEN NOT MATCHED THEN
INSERT (intID1,intID2,intID3)
VALUES (t.intID1,t.intID2,t.intID3)
Nice and simple with EXCEPT
INSERT INTO #temptable (intID1, intID2, intID3)
SELECT intID1,intID2,intID3 FROM TableA
EXCEPT
SELECT intID1,intID2,intID3 FROM #temptable
I see where you are coming from. In most programming languages #temptable would be a variable (a relation variable or relvar for short) to which you would assign a value (a relation value) thus:
#temptable := #temptable UNION A
In the relational model, this would achieve the desired result because a relation has no duplicate rows by definition.
However, SQL is not truly relational and does not support assignment. Instead, you are required to add rows to a table using SQL DML INSERT statements (which is not so bad: the users of a truly relational database language, if we had one, would no doubt demand a similar shorthand for relational assignment!) but you are also required to do the test for duplicates yourself.
The answers from Daniel Hilgarth and Joachim Isaksson both look good. It's good practice to have two good, logically sound candidate answers then look for criteria (usually performance under typical load) to eliminate one (but retaining it commented out for future re-testing!)