I want to make a function in PostgreSQL that would make the following:
First of all read some data from a table lets say “Select col1,col2 from table1”
Then for each row of the above selection I want to make an insert to an other table lets say table2 (that contains some extra columns like date and so on).
For each insertion I want a unique key that starts from a given number and is increased in every new row.
Can someone give me an example about how I can do it?
I need to be more specific
I want to do what is discribed below:
For(every row in table1)
if(table1.col1>0)
insert into table2 (c1,c2,c3,c4) nalues (id,table1.col1,table1.col2,'oposite',current_timestamp)
else if(table1.col1<0)
insert into table2 (c1,c2,c3,c4) nalues (id,table1.col1,table1.col2,'negative',current_timestamp)
id+=1
insert table2(id, col1, col2)
select startingpoint-1+row_number() over (order by col1, col2),
col1,
col2
from table1
You can use select into to do this, just set up the second table with an autoincrementing field and it will give you your unique key.
Related
I have two tables. They have an identical structure except for the fact that Table2 has one more column. I want to create a stored procedure that copies all the data from Table1 to Table2, and then insert data into the unique column in Table2. I am kinda stumped, all I have so far is this:
CREATE PROCEDURE insert_t_p #t_p INT AS
BEGIN
INSERT INTO table_2
SELECT * FROM table_1
END
where #t_p is the data that I want to insert. This is going to be constant for all the records being copied over. Does anyone have any suggestions?
I suspect that you want:
INSERT INTO table_2 SELECT *, #t_p FROM table_1
Note that you should really enumerate the columns in both the insert and select, like:
INSERT INTO table_2(col1, col2, col3)
SELECT col1, col2, #t_p FROM table_1
This makes it much easier to ensure that each column from the source table is going into the relevant target column, possibly makes the query resilient to changes in the data structures, and allows you to handle structures where columns have different orders.
I strongly recommend that you list the columns:
INSERT INTO table_2 (col1, col2, . . . , col_extra)
SELECT col1, col2, . . ., #t_p
FROM table_1 ;
Listing the columns is a good habit that ensures that your code works with fewer errors and is not prone to issue if the table structures change -- or the columns are declared in a different order.
I am selecting all column of my table (eg 40 columns) and i want to rename only one column (e.g col20 ). how can i rename this column in my select query while selecting all column using select *. I don't want to write the name of all column. one more thing i also don't want to change the order of column in my table
Short answer is, you can't.
Either you have to select all the columns individually, using
select col1, col2, col3, ..., col20 as NewCol, ...., col40 from table
or use
select * from table
You can't have both.
Another option is there which you can use like below, but this will add an extra column in the output.
select t.*, t.col20 as NewCol from table t
i have one table test it has 10 column with 20 rows.
I need to move this data to archive_test table which has 11 column (10 same as test table plus one column is archive date).
when i tried to insert like below its shows error because number of column mismatch.
insert into archive_test
select * from test;
Please suggest the better way to do this.Thanks!
Well, obviously you need to supply values for all the columns, and although you can avoid doing so you should also explicitly state whic value is going to be inserted into which column. If you have an extra column in the target table you either:
Do not mention it
Specify a default value as part of its column definition in the table
Have a trigger to populate it
Specify a value for that column.
eg.
insert into table archive_test (col1, col2, col3 ... col11)
select col1,
col2,
col3,
...
sysdate
from test;
assuming that archive_date is the last column:
INSERT INTO archive_test
SELECT test.*, sysdate
FROM test
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..
Im trying to copy the contents from a column in one table to another and at the same time want to populate the primary key column with an incrementing number for each row created:
I have tried doing the following:
INSERT INTO Table1 (col1, col2) VALUES((SELECT col1 FROM table2), (SELECT NEXTVAL FOR col2_SEQ FROM sysibm.sysdummy1));
but get the following error:
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0348N "NEXTVAL FOR col2_SEQ" cannot be specified in this
context. SQLSTATE=428F
It seems that i cant use the sequence value in this way, is there any other way I can achieve what I'm trying to do? I just need col2 in table1 to be populated with a unique BIGINT for each new entry from col1 from table2
If you're on Linux/Unix/Windows (and probably for others), I think you just want NEXT VALUE FOR sequence. You don't need the extra select from sysdummy in this context.
INSERT INTO table1 (col1, col2)
SELECT col1, NEXT VALUE FOR col2_SEQ
FROM table2
There are 3 methods in which unique values can be generated in DB2.
GENERATE_UNIQUE function
IDENTITY column
SEQUENCE object
Assuming col2_SEQ is created similar to below statement:
CREATE SEQUENCE col2_SEQ
AS INTEGER
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
NO CYCLE
ORDER
The insert statement can be written as follows:
INSERT INTO Table1 (col1, col2)
VALUES ((SELECT col1 FROM table2),
NEXT VALUE FOR col2_SEQ)
More information, on each of the three methods mentioned above, can be found here
There is also alternative syntax now, which worked for me in DB2 10.x
INSERT INTO table1 (col1, col2)
SELECT col1, schema.seq_name.nextval
FROM table2;
Maybe you should specify the columns as:
col2 smallint not null
generated by default as identity (start with 1, increment by 1)
and insert into table1 select col1, default from table2