How Can I Use the Max Function to Filter a List and Insert Into - sql

Is there a way to do something like:
Insert Into (col1, col2, col3)
Select col1, col2, col3, max(col4)
From mytable
Group By col1, col2, col3
That gives me: The select list for the INSERT statement contains more items than the insert list.
I want to use the max function to filter out dupes but when I select this extra field, the order of fields and number of fields doesn’t match up. How can I filter a list from a table, use the max function, and insert all records except the ones in the max field?

I want to use the max function to filter out dupes
Well, I suspect that you actually want distinct:
insert into my_target_table(col1, col2, col3)
select distinct col1, col2, col3 from my_source_table
This will insert one record in the target table for each distinct (col1, col2, col3) tuple in the source table.

You are describing something like this:
Insert Into (col1, col2, col3)
select col1, col2, col3
from mytable
where t.col4 = (select max(t2.col4)
from mytable t2
where t2.col1 = t.col1 and t2.col2 = t.col2 and t2.col3 = t.col3
);
However, this is pretty much equivalent to select distinct (NULL values might be treated differently). You probably want dupes defined on only one column, so I'm thinking:
insert into (col1, col2, col3)
select col1, col2, col3
from mytable
where t.col4 = (select max(t2.col4)
from mytable t2
where t2.col1 = t.col1
);

Related

pl/sql insert from select

I have tow tables:
table1 with 5 columns
table2 with 4 columns
I want to copy the data from table2 to table1.
In table1 I have column with default value, let's say column2 ='default'
How i do it in PL/SQL?
You can insert and enumerate the target columns. The idea is:
insert into table1(col1, col3, col4, col5)
select col1, col2, col3, col4 from table2
The "additional" column of table1 (I assumed col2) is not part of the list of columns to insert into - so Oracle will happily use the configured default value.
You can simply use the constant value for the col2 as follows:
insert into table1(col1, col2, col3, col4, col5)
select col1, 'default', col2, col3, col4 from table2;

Concatenate tables (UNION ALL) where one of the tables lacks one of the columns

I am trying to combine three tables in an SQLite database into one new combined table. The three tables have the same column names, but the third table is missing one of the columns. Here is how I am trying to do it:
CREATE TABLE cobmined
AS
SELECT col1, col2, col3
FROM
(
SELECT col1, col2, col3 from table1
UNION ALL
SELECT col1, col2, col3 from table2
UNION ALL
SELECT col1, col2 from table3
) s
;
This works when doing this only on the first two tables, when adding the third table I get the message:
SELECTs to the left and right of UNION do not have the same number of result columns
Is there a way to let SQL ignore the missing column and leave it with NULLs if needed?
Add a NULL value to the third table
CREATE TABLE cobmined
AS
SELECT col1, col2, col3
FROM
(
SELECT col1, col2, col3 from table1
UNION ALL
SELECT col1, col2, col3 from table2
UNION ALL
SELECT col1, col2, null from table3
) s
;
Also, no need for sub-query
CREATE TABLE cobmined
AS
SELECT col1, col2, col3 from table1
UNION ALL
SELECT col1, col2, col3 from table2
UNION ALL
SELECT col1, col2, null from table3
I want to note that you don't need the subquery:
CREATE TABLE combined AS
SELECT col1, col2, col3 from table1
UNION ALL
SELECT col1, col2, col3 from table2
UNION ALL
SELECT col1, col2, NULL from table3;
In addition, you may find that a view is more suitable for your purposes than an actual table.

INSERT INTO using a query, and add a default value

I want run an INSERT INTO table SELECT... FROM...
The problem is that the table that I am inserting to has 5 columns, whereas the table I am selecting from has only 4. The 5th column needs to be set do a default value that I specify. How can I accomplish this? The query would be something like this (note: this is Oracle):
INSERT INTO five_column_table
SELECT * FROM four_column_table
--and a 5th column with a default value--;
Just add the default value to your select list.
INSERT INTO five_column_table
SELECT column_a, column_b, column_c, column_d, 'Default Value'
FROM four_column_table;
Just select the default value in your SELECT list. It's always a good idea to explicitly list out columns so I do that here even though it's not strictly necessary.
INSERT INTO five_column_table( col1, col2, col3, col4, col5 )
SELECT col1, col2, col3, col4, 'Some Default'
FROM four_column_table
If you really don't want to list out the columns
INSERT INTO five_column_table
SELECT fct.*, 'Some Default'
FROM four_column_table fct
Oracle supports a keyword DEFAULT for this purpose:
insert all
into five_column_table( col1, col2, col3, col4, col5 )
VALUES( col1, col2, col3, col4, DEFAULT)
SELECT col1, col2, col3, col4
FROM four_column_table;
But in your case I had to use multi-table insert. DEFAULT keyword can be used only in values clause.

Oracle: Insert into select... in the

What is the advantage of inserting into a select of a table over simply inserting into the table?
eg
insert into
( select COL1
, COL2
from Table1
where 1=2 <= this and above is the focus of the question.
) select COL3, COL4 from Table2 ;
It seems to do the same thing as:
insert into Table1
( COL1, COL2 )
select COL3, COL4 from Table2 ;
This is the first time I've seen this; our Sr Dev says there is some advantage but he can't remember what it is.
It may make sense in a way if one was inserting a "select *..." from a table with lots of columns, and we want to be lazy, but... we're not. We're enumerating each column in the table.
Database is Oracle 11gR2, but this query was written probably in 10g or before.
we want to be lazy
No, we use insert into table(col1, col2) select col2, col2 from ... when there is a lot of records (for example 1M) and we don't want to create a the values section for each. Let's imagine how much time it takes if you write
insert into table (col1, col2)
values (select col1, col2 from (select col1, col2, rownum rn from ...) where rn = 1);
insert into table (col1, col2)
values (select col1, col2 from (select col1, col2, rownum rn from ...) where rn = 2);
...
insert into table (col1, col2)
values (select col1, col2 from (select col1, col2, rownum rn from ...) where rn = 1000000);
insert select is faster way for copying data from one table(several tables) to an another table.
In a nutshell. It's a lot easier. Especially when you have a massive query that you dont wanna rebuild,or if you have a crapton of objects, or values you are inserting.
Without WITH CHECK OPTION specified, I don't know of any purpose for this syntax. If you specify WITH CHECK OPTION, you can effectively implement an ad-hoc check constraint within your insert statement.
insert into
( select COL1
, COL2
from Table1
where 1=2 WITH CHECK OPTION
) select COL3, COL4 from Table2 ;
The above will never insert a record, because 1 will never equal 2.
The statement below will insert a record as long as COL3 is less than 100, otherwise an exception is raised.
insert into
( select COL1
, COL2
from Table1
where COL1 < 100 WITH CHECK OPTION
) select COL3, COL4 from Table2 ;

PL/SQL Inserting into a table minus another table but inserting another column at the same time

I have a small problem, say I have a table with 5 columns, I insert into that table using MINUS from another table that has 4 columns.
I am having problem inserting a (null) or ' ' value into the 5th column when I do that statement as it says:
invalid number of columns selected (table I am minusing from does not have the 5th column)
This is my code I use for the insert into statement
INSERT INTO my_table(SELECT col1, col2, col3, col4 FROM that_table
MINUS SELECT col1, col2, col3, col4 FROM my_table);
This code works, it copies whatever I need if I don't create a 5th column, is there a way to insert into my table values from the other table alongside a 5th column in my_table?
Thank you
Assuming I'm understanding your question, you want to select all records from that_table and insert those into my_table where the first 4 columns don't exist, using null as the value for the 5th column? If so, you can use not exists:
insert into my_table (col1, col2, col3, col4, col5)
select col1, col2, col3, col4, null
from that_table tt
where not exists (
select 1
from my_table mt
where tt.col1 = mt.col1 and tt.col2 = mt.col2
and tt.col3 = mt.col3 and tt.col4 = mt.col4
)
You should also be able to use Minus, just make sure you have the same number of columns and same data types:
insert into my_table (col1, col2, col3, col4, col5)
select col1, col2, col3, col4, null
from that_table
minus
select col1, col2, col3, col4, null
from my_table
If you want to insert only the selected columns, then try this:
insert into my_table (col1, col2, col3, col4, col5) select col1, col2, col3, col4, null from that_table;
You can find more information at http://www.w3schools.com/sql/sql_insert_into_select.asp