INSERT INTO ... SELECT with more SELECT columns - sql

Thank you for your time.
I have a INSERT INTO ... SELECT setup, but I also want to filter using extra columns (that do not exist in the table I am inserting into)
For example:
INSERT INTO table1 (t1_col1, t1_col2, t1_col3)
SELECT
t2.t1_col1,
t2.t1_col2,
t3.t1_col3,
t4.filter_col
FROM table2 t2
INNER JOIN table3 t3 ON t2.t1_col1 = t3.t1_col1
INNER JOIN table4 t4 ON t4.filter_col = t2.filer_col
WHERE t4.filter_col = 'value';
table1 only has columns t1_col1, t1_col2 and t1_col3 so when I attempt to run this it fails as expected:
ERROR: INSERT has more expressions than target columns
So my question is, how can I still include the filter, but specify which columns from my SELECT statement should be used in the INSERT INTO statement.
Many thanks for any help!

you have to same number of column in select ,so remove t4.filter_col from selection
INSERT INTO table1 (t1_col1, t1_col2, t1_col3)
SELECT
t2.t1_col1,
t2.t1_col2,
t3.t1_col3
FROM table2 t2
INNER JOIN table3 t3 ON t2.t1_col1 = t3.t1_col1
INNER JOIN table4 t4 ON t4.filter_col = t2.filer_col
WHERE t4.filter_col = 'value';
Note: you are not bound to select all columns those you used in join or filter

It's almost right, but you select one column too much. Try this:
INSERT INTO table1 (t1_col1, t1_col2, t1_col3)
SELECT
t2.t1_col1,
t2.t1_col2,
t3.t1_col3
FROM table2 t2
INNER JOIN table3 t3 ON t2.t1_col1 = t3.t1_col1
INNER JOIN table4 t4 ON t4.filter_col = t2.filer_col
WHERE t4.filter_col = 'value';

Related

Inner join the tables where the value of one column is different. But the meaning of the values are same

Table t1
Table t2
I tried running the query
select CountyCode, ContactPerson
from table1 t1
inner join select * from table 2 t2 on t1.CountyCode[1] = Code[0]
Any one help me please.
Use this syntax:
select CountyCode, ContactPerson
from t1
inner join t2 on t1.CountyCode = t2.Code

specifying count in WHERE clause

select *
from table1 t1,
table2 t2,
table3 t3
where t2.parent_id = t1.row_id
and t2.xyz is not null
and (
select count(*)
from table3
where xyz = t2.row_id
) = 0;
Will it work?
I am using the alias t2 within my subquery.
My requirement is to check is to specify condition in where clause such that there is no record present in table3 where column xyz of table3 is stored as row_id of table2.
You can use NOT EXISTS to assert that there is no row returned from the subquery. Use modern explicit join syntax instead of comma based legacy syntax. No need to join table3 outside (you were making a cross join effectively).
select *
from table1 t1
join table2 t2 on t2.parent_id = t1.row_id
where t2.xyz is not null
and not exists (
select 1
from table3
where xyz = t2.row_id
);

SQL JOIN USING and WHERE

This is somewhat of a followon to SQL JOIN where to place the WHERE condition?
I would prefer to use the USING clause on the join, but am not yet able to put the field value condition with the join.
SELECT 1
FROM table1 t1
JOIN table2 t2 USING(id) AND t2.field = 0;
ORA-00933: SQL command not properly ended
Is it possible to have USING and another condition as part of the JOIN clause?
You can use:
SELECT 1
FROM table1 t1
JOIN table2 t2 USING(id)
WHERE t2.field = 0;
Using USING(id) is like using ON t1.id = t2.id except that in the JOIN result instead of two columns t1.id & t2.id there is only one id column.
For INNER JOIN USING with a condition followed by an OUTER JOIN you need a subquery to keep the WHERE with the USING:
SELECT ...
FROM (SELECT id, ...
FROM table1 t1
JOIN table2 t2 USING(id)
WHERE t2.field = 0) s
LEFT JOIN ...;
For an OUTER JOIN USING with a condition you need a subselect:
SELECT ...
FROM table1 t1
LEFT JOIN (SELECT *
FROM table2 t2
WHERE t2.field = 0) t2
USING (id);
See this re ON/WHERE with JOIN. See this re ON/WHERE when mixing INNER & OUTER JOINs.

SQL join order and conditions

I've got 3 tables that I want to join and filter on some conditions.
I've first wrote this query:
select * from table1 t1
left join (select * from table2 where table2.fieldX=...) t2
on t1.id_12=t2.id_12
left join table3
on t2.id_23=t3.id_23
where t1.fieldY=...
Then I wanted to make it looks like more canonical by rewritting it like that:
select * from table1 t1
left join table2 t2
on t1.id_12=t2.id_12
left join table3
on t2.id_23=t3.id_23
where table2.fieldX=...
and t1.fieldY=...
But it does not give the same result.
I dont't understand why...
Do you?
Thanks in advance.
When you put table2.fieldX=... in the where clause you eliminate all rows from table1 that do not have a corresponding row in table2. Effectively you are changing the left join into an inner join.
Instead, you can apply the table2 filter in the join itself:
SELECT
*
FROM
Table1 t1
LEFT JOIN Table2 t2 ON t1.id_12 = t2.id_12 AND t2.fieldX = ...
LEFT JOIN Table3 t3 ON t2.id_23 = t3.id_23
WHERE
t1.fieldY = ...
Did you add the inner select where on the second query?
SELECT *
FROM table1 t1
LEFT JOIN table2 t2
on t1.id_12=t2.id_12
LEFT JOIN table3
on t2.id_23=t3.id_23
WHERE t1.fieldY=...
and t2.fieldX=...

t-sql table join

Is there any way I can do a join between two tables where the resulting table has only the columns of the left table without the need to discriminate all the columns names in the select?
You can do this:
Select LeftTable.*
From LeftTable
Inner Join RightTable
On LeftTable.Id = RightTable.Id
Select T.* from tbl1 T, tbl2 J
You mean something like
Select t1.id, t1.name, t1.age FROM t1 INNER JOIN t2 ON t1.id = t2.id
WHERE t2.Something = Something