How to do INSERT INTO updated data from another table? - sql

I have a new table (called "NewTable") which is created with the data from 2 tables (t1 and t2). I am trying to INSERT any new data in t1 and t2 INTO "NewTable". Please see the example below.
NewTable:
id | col1 | col2 | col3 | col4 |
t1:
id | col1 | col2 | col5 | col6 |
t2:
id | col3 | col4 | col7 | col8 |
my script is:
INSERT NewTable (id, col1, col2, col3, col4)
SELECT t1.d1, col1, col2, col3, col4
FROM NewTable left join t1 on NewTable.id = t1.id left join t2 on t1.id=t2.id
WHERE t1.id is NULL;
I got this error message
Cannot insert the value NULL into column 'id', table 'New Table'; column does not allow nulls. INSERT fails.
I feel like my script is off. Should I use right join instead of left join or should I put "WHERE NewTable is NULL" instead?
Thank you for your help

If you want to insert into NewTable rows from t1 and t2 with the same id that don't already exist in NewTable then you must join with an INNER join t1 and t2, then LEFT join NewTable and return the non matching rows:
INSERT INTO NewTable (id, col1, col2, col3, col4)
SELECT t1.id, t1.col1, t1.col2, t2.col3, t2.col4
FROM t1 INNER JOIN t2 ON t2.id = t1.id
LEFT JOIN NewTable ON NewTable.id = t1.id
WHERE NewTable.id IS NULL;

Related

SQL join two tables that have the same columns, with an overlapping `id` column, but merge based on if table1.col1 >= table2.col1

I want to join two tables that have the same columns, with an overlapping id column, but merge based on if table1.col1 >= table2.col1. This is in SQL.
If table1.col1>=table2.col1, use the columns from table1.
If table1.col1< table2.col1, then use columns from table2.
If the id does not exist in table1 but exists in table2, use the columns from table2
If the id does not exist in table2 but exists in table1, use the columns from table1
For example:
Table1:
id
col1
col2
col3
A
3
5
4
B
1
2
3
C
8
9
7
Table2:
id
col1
col2
col3
A
2
5
6
B
5
7
8
D
2
3
4
I want the result to be:
id
col1
col2
col3
A
3
5
4
B
5
7
8
C
8
9
7
D
2
3
4
I have tried union, full outer join, and CASE statements, but am stuck
I think individual case expressions for each column might be best:
select id,
(case when t1.col1 < t2.col1 then t2.col1 else t1.col1 end) as col1,
(case when t1.col1 < t2.col1 then t2.col2 else t1.col2 end) as col2,
(case when t1.col1 < t2.col1 then t2.col3 else t1.col3 end) as col3
from t1 full join
t2
using (id);
If that is cumbersome, another approach uses not exists:
select t1.*
from t1
where not exists (select 1
from t2
where t2.id = t1.id and t2.col1 > t1.col1
)
union all
select t2.*
from t2
where not exists (select 1
from t1
where t2.id = t1.id and t1.col1 >= t2.col1
);
Another solution:
SELECT DISTINCT ON (id) *
FROM (
SELECT *
FROM table1
UNION ALL
SELECT *
FROM table2
) AS aux
ORDER BY id, col1 DESC;
I tried it in Postgresql.

SQL Compare rows of a table with multiple columns

I have a table T1
Id
Col1
Col2
IsActive
1
T1
v1
1
2
T2
v2
0
Now received the following data and it need to be inserted into the above table.
| Col1 | Col2 |
|--------|--------|
| T1 | v1 |
| T2 | v2 |
| T3 | v3 |
As this data contains some duplicated values, it need to be inserted based on IsActive Column value. For row with IsActive 1, need to insert with IsActive 2 and for row with IsActive 0, need to insert with IsActive 1 like below, the unique data need to be inserted with IsActive 1 and that is not a problem right now
Id
Col1
Col2
IsActive
1
T1
v1
1
2
T2
v2
0
3
T1
v1
2
4
T2
v2
1
5
T3
v3
1
I have created a Temp table #Temp and inserted common rows in new incoming data and data from existing table like below:
#Temp
Col1
Col2
IsActive
T1
v1
1
T2
v2
0
T1
v1
NULL
T2
v2
NULL
Using Group By I can able to select duplicate rows but I need to insert based on IsActive value, so I stuck here.
insert into T1
select Col1, Col2, '1' from #Temp
GROUP BY Col1, Col2
HAVING COUNT(Col1) > 1
I need help on this above part, thanks in advance
Try this:
-- create temp table with values to be inserted
INSERT INTO #ToInsert
([Col1], [Col2])
VALUES
('T1', 'v1'),
('T2', 'v2'),
('T3', 'v3')
-- join each value of the temp table to the original table. if
-- value exists increment its `IsActive` by 1, otherwise set it to 1
INSERT INTO t (Col1, Col2, IsActive)
SELECT i.Col1, i.Col2, COALESCE(t.IsActive + 1, 1) AS IsActive
FROM #ToInsert i
LEFT JOIN (
SELECT Col1, Col2, max(IsActive) as IsActive
FROM t
GROUP BY Col1, Col2
) t ON i.Col1 = t.Col1 AND i.Col2 = t.Col2
Demo here

Merge columns and Sub Select list

My query simply looks like:
SELECT col1, col2,
(SELECT col3, col4 FROM Table2)
FROM Table1
Wanted result is:
col1 | col2 | col3 | col4
-------------------------
ABC | DEF | GHI | JKL
... | ... | ... | ...
But I am getting an error:
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
How to merge lists and current rows?
You probably want something like this:
SELECT col1,
col2,
(SELECT col3 FROM Table2 as t2 WHERE t2.id = t1.id) as col3,
(SELECT col4 FROM Table2 as t2 WHERE t2.id = t1.id) as col4
FROM Table1 as t1
or even better:
SELECT t1.col1,
t1.col2,
t2.col3,
t2.col4
FROM Table1 as t1
JOIN Table2 as t2
ON t1.id = t2.id
if you don't have a field to join both tables then:
SELECT t1.col1,
t1.col2,
t2.col3,
t2.col4
FROM Table1 as t1
CROSS JOIN Table2 as t2

SQL Join with 2 columns when one of them is NULL/Blank

Let's say I have 2 tables like this:
I want to join both #tmp1 & #tmp2 for Columns : Col2 & Col3 . But if the value of either of these columns is blank or Null, I want to ignore that column and just look at one.
So for example here, when I join where Col2 is ABC, I should get both DEF & Blank for Col3.
I hope I'm making some sense here. Apologize if it's not clear enough.
I can't tell from your example what columns you want to join but to solve the "null" problem you do it like this
SELECT *
FROM T1
JOIN T2 ON COALESCE(T1.COL1,T2.COL1) = T2.COL1
AND COALESCE(T1.COL2,T2.COL2) = T2.COL2
If T1.COL1 or T1.COL2 are null it will use the value of the table it is joining to. This allows null to be a "wildcard".
or if T2 is the table with nulls
SELECT *
FROM T1
JOIN T2 ON T1.COL1 = COALESCE(T2.COL1,T1.COL1)
AND T1.COL2 = COALESCE(T2.COL2,T1.COL2)
You can use union for this checking if at least 1 of the 2 columns is the same using exists:
select col1, col2, col3
from tmp1 t1
where exists (select 1
from tmp2 t2
where t1.col2 = t2.col2 or t1.col3 = t2.col3)
union
select col1, col2, col3
from tmp2 t2
where exists (select 1
from tmp1 t1
where t1.col2 = t2.col2 or t1.col3 = t2.col3)
Fiddle Demo
Results:
| col1 | col2 | col3 |
|-------|------|------|
| test1 | abc | def |
| test2 | aaa | bbb |
| test1 | abc | |
| test2 | ccc | bbb |

Comparing two tables with SQL

I need a query to produce a compare table between two tables.
Something like this:
table_1:
col1 | col2 | col3
a | 1 | a_comment
b | 2 | b_comment
table_2:
col1 | col2 | col3
a | 3 | a_comment
c | 4 | c_comment
Query result:
col1 | table_1.col2 | table_2.col2 | col3
a | 1 | 3 | a_comment
b | 2 | NULL | b_comment
c | NULL | 4 | c_comment
Also, I need to keep the order, s.t. if x in col1 is before y in col1 in any of the tables it will also be before it in the query result.
I tried to do it with FULL JOIN but it duplicates col1 and col3.
Thank you!
select t1.col1, t1.col2, t2.col2, t1.col3
from table_1 t1
left join table_2 t2
on t1.col1 = t2.col1
and t1.col3 = t2.col3
union
select t2.col1, t2.col2, t1.col2, t2.col3
from table_2 t2
left join table_1 t1
on t2.col1 = t1.col1
and t2.col3 = t1.col3
Full join is ok i think, you just have to select not all but just what you want, like
SELECT ISNULL(table_1.col1, table_2.col1) col1, table_1.col2, table2.col2, ISNULL(table_1.col3, table_2.col3) col3
ISNULL might be called different depending on what database system u use
SELECT col1
, t1.col2
, t2.col3
, col3
FROM table1 t1
FULL OUTER JOIN table2 t2
USING (col1, col3)