Insert/update a flag depending on values matched between to tables - sql

I want to make a procedure where:
If an ID exists in table B but not in Table A code with be inser/updated to 0.
Else if the ID exists in both table code field will be insert/updated to 1.
I have two tables, for example:
Table A Table B
+----+--+--+----+------+
| ID | | | Id | Code |
+----+--+--+----+------+
| 1 | | | 1 | 0 |
| 2 | | | 2 | 0 |
| 3 | | | 3 | 0 |
| 4 | | | 4 | 0 |
| | | | 5 | 0 |
| | | | 6 | 0 |
+----+--+--+----+------+
Can you please help me with that?
Table B in the end should be like this:
+----+------+
| Id | Code |
+----+------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 5 | 0 |
| 6 | 0 |
+----+------+

Something like this: make left join to generate values of table B, which not present in table A, then merge to update column Code.
merge into table_b
using (select b.id, case when a.id is null then 0 else 1 end code
from table_b b left join table_a a on a.id = b.id) t
on (t.id = table_b.id)
when matched then update
set code = t.code

You can use MERGE:
MERGE into tableB B
USING tableA A
ON (a.id = b.id)
WHEN MATCHED THEN
UPDATE SET code = 1
WHEN NOT MATCHED THEN
INSERT (id,code) values (a.id, 0)

Please find the answer below for your question...,
create table TABLEA (ID int);
insert into TABLEA (ID) values (1);
insert into TABLEA (ID) values (2);
insert into TABLEA (ID) values (3);
insert into TABLEA (ID) values (4);
insert into TABLEA (ID) values (5);
create table TABLEB (ID int, code int);
insert into TABLEB (ID,code) values (1,0);
insert into TABLEB (ID,code) values (2,0);
insert into TABLEB (ID,code) values (3,0);
insert into TABLEB (ID,code) values (4,0);
insert into TABLEB (ID,code) values (5,0);
insert into TABLEB (ID,code) values (6,0);
insert into TABLEB (ID,code) values (7,0);
insert into TABLEB (ID,code) values (8,0);
UPDATE TABLEB SET CODE=1 FROM TABLEB B INNER JOIN TABLEA as A on A.id=B.id;
SELECT * FROM TABLEB;
ID CODE
1 1
2 1
3 1
4 1
5 1
6 0
7 0
8 0

Related

How do insert data into a table that already exists?

I'm trying to insert data into a table that already exists, but I cant find anything on how to do this. I only found how to insert this data into a new table.
Syntax error at or near Insert
Tutorial I visited
SELECT film_category.film_id, film_category.category_id, rental_duration, rental_rate
INSERT INTO category_description
FROM film_category
LEFT JOIN FILM
ON film_category.film_id = film.film_id
A simplified test to showcase methods to insert.
CREATE TABLE TableA (
ID INT GENERATED ALWAYS AS IDENTITY,
ColA1 INT,
ColA2 VARCHAR(30)
);
--
-- INSERT VALUES into existing table
--
INSERT INTO TableA (ColA1, ColA2) VALUES
(10, 'A'),
(20, 'B'),
(30, 'C');
3 rows affected
--
-- SELECT INTO new table
--
SELECT ID, ColA1+2 AS ColB1, ColA2||'2' AS ColB2
INTO TableB
FROM TableA;
3 rows affected
--
-- INSERT from SELECT with explicit columns
--
INSERT INTO TableA (ColA1, ColA2)
SELECT ColB1+1, CONCAT(LEFT(ColB2,1),'3') AS ColB23
FROM TableB;
3 rows affected
SELECT * FROM TableA;
id | cola1 | cola2
-: | ----: | :----
1 | 10 | A
2 | 20 | B
3 | 30 | C
4 | 13 | A3
5 | 23 | B3
6 | 33 | C3
--
-- INSERT from SELECT without columns
-- Only works when they have the same number of columns.
--
INSERT INTO TableB
SELECT *
FROM TableA;
6 rows affected
SELECT * FROM TableB;
id | colb1 | colb2
-: | ----: | :----
1 | 12 | A2
2 | 22 | B2
3 | 32 | C2
1 | 10 | A
2 | 20 | B
3 | 30 | C
4 | 13 | A3
5 | 23 | B3
6 | 33 | C3
db<>fiddle here
The order is wrong https://www.w3schools.com/sql/sql_insert_into_select.asp
Also see this answer
Insert into ... values ( SELECT ... FROM ... )
INSERT INTO category_description
SELECT
film_category.film_id,
film_category.category_id,
rental_duration,
rental_rate
FROM
film_category
LEFT JOIN FILM ON film_category.film_id = film.film_id

Merge statement that allows insertion of duplicates

I have two tables,
Table 1
Id | medicineName
-------------------------
1 | benalgin
2 | xanax
3 | xanax
-------------------------
And I have this second table, where I need to insert the ID from the above table into the second table (which has null values in the medicineId column), and I need to use MERGE statement that will allow me to insert duplicates.
Table 2
medicineId | medicine
-------------------------
null | xanax
null | xanax
null | operil
-------------------------
I have tried this, but since I need to have duplicate records with different ID, I get the error:
cannot insert or update duplicate rows
MERGE table2 b
USING table1 a
ON (a.MedicineName = b.Medicine and a.Id is null)
when matched
then update set
a.Id = b.MedicineId;
I think that you do need two queries for this.
First update the existing records in table2 with one of the ids coming from table1:
update table2
set medicineId = (
select min(id) from table1 t1 where t1.medicineName = table2.medicine
)
Then insert the missing records:
insert into table2 (medicineId, medicine)
select id, medicineName
from table1 t1
where not exists (
select 1 from table2 t2 where t2.medicineId = t1.id and t2.medicine = t1.medicineName
)
Demo on DB Fiddle
Table content after update:
MEDICINEID | MEDICINE
:--------- | :-------
2 | xanax
2 | xanax
null | operil
Table content after insert:
MEDICINEID | MEDICINE
:--------- | :-------
2 | xanax
2 | xanax
null | operil
3 | xanax
1 | benalgin

Showing the full list IDs when OUTER JOIN two tables

How to display not only the overlapped IDs from two tables (table A and table B) but also the unique IDs from two tables?
Here is the example code:
SELECT A.ID AS ID
FROM A
FULL OUTER JOIN B ON A.ID = B.ID
I think there's something I can do with the SELECT line but I don't know how.
coalesce() returns the first non-null value from a set of parameters. Is that what you are looking for?
rextester demo: http://rextester.com/QYAZV8300
create table a (id int)
insert into a values (1),(3),(5)
create table b (id int)
insert into b values (2),(3),(4)
select
a.id as A_Id
, b.id as B_Id
, coalesce(a.id,b.id) as Id
from a
full join b
on a.id = b.id
returns:
+------+------+----+
| A_Id | B_Id | Id |
+------+------+----+
| 1 | NULL | 1 |
| 3 | 3 | 3 |
| 5 | NULL | 5 |
| NULL | 2 | 2 |
| NULL | 4 | 4 |
+------+------+----+

How to get a join where the left row is only shown once

I have a two tables, TableA and TableB. TableB has multiple records for 1 TableA record. If I join the two I get the following:-
SELECT TableA.OrderId, TableA.OrderDate, TableB.Description,TableB.Quantity
from TableA
INNER JOIN on TableA.OrderId = TableB.OrderId
TableA.OrderId | TableA.OrderDate | TableB.Description | TableB.Quantity
1 | 24/12/2015 | Banana | 10
1 | 24/12/2015 | Apple | 5
1 | 24/12/2015 | Pear | 7
1 | 24/12/2015 | Orange | 3
Does anyone know how to get the following output? :-
TableA.OrderId | TableA.OrderDate | TableB.Description | TableB.Quantity
1 | 24/12/2015 | Banana | 10
| Apple | 5
| Pear | 7
| Orange | 3
Many hours of fruitless searching with no joy!
Check this
create table TableA(OrderId int not null,
OrderDate date null)
insert into TableA Values(1,'12/24/2015')
create table TableB(OrderId int not Null,
Description varchar(50) null,
Quantity int null)
insert into TableB values(1,'Banana',10)
insert into TableB values(1,'Apple',5)
insert into TableB values(1,'Pear',7)
insert into TableB values(1,'Orange',3)
select case when ttt.RowNum=1 then convert(varchar(50),ttt.OrderId) else '' end,
case when ttt.RowNum=1 then convert(varchar(50),ttt.OrderDate) else '' end,
ttt.Description,
ttt.Quantity
from
(select a.OrderId
,a.OrderDate
,b.Description,
b.Quantity
,RowNum = ROW_NUMBER() OVER (PARTITION BY a.OrderId ORDER BY 1/0)
from TableA a join TableB b on a.OrderId=b.OrderId) as ttt

Update from another table Oracle

Table1
Tripid sequence Pattern
1 1
1 2
1 3
2 1
2 2
Table2
Tripid Pattern
1 A
2 B
I'm trying to update Pattern for table 1, end result should be:
Tripid sequence Pattern
1 1 A
1 2 A
1 3 A
2 1 B
2 2 B
The code that I use:
update table1
set table1.pattern =
(select pattern from table2 where table1.tripid = table2.tripid)
where exists
(select pattern from table2 where table1.tripid = table2.tripid)
Oracle Database Error: ORA-01427: single-row subquery returns more than one row
How to do it correctly in oracle 10g?
You can use MERGE statement for this.
Query:
select * from t1
Result:
| TRIPID | SEQ | PATTERN |
|--------|-----|---------|
| 1 | 1 | (null) |
| 1 | 2 | (null) |
| 1 | 3 | (null) |
| 2 | 1 | (null) |
| 2 | 2 | (null) |
Query:
merge into t1
using t2
on (t1.tripid = t2.tripid)
when matched then update
set pattern = t2.pattern
Query:
select * from t1
Result:
| TRIPID | SEQ | PATTERN |
|--------|-----|---------|
| 1 | 1 | A |
| 1 | 2 | A |
| 1 | 3 | A |
| 2 | 1 | B |
| 2 | 2 | B |
Maybe, tripid is not unique in table2?
It is in your example, but is it unique in your real data?
DROP table table1;
create table table1(tripid number, sequence number, pattern CHAR(1));
insert into table1 values (1,1,null);
insert into table1 values (1,2,null);
insert into table1 values (1,3,null);
insert into table1 values (2,1,null);
insert into table1 values (2,2,null);
DROP table table2;
create table table2(tripid number, pattern CHAR(1));
insert into table2 values (1,'A');
insert into table2 values (2,'B');
commit;
select table2.tripid, table2.pattern from table2,table1 where table1.tripid = table2.tripid;
update table1
set table1.pattern =
(select pattern from table2 where table1.tripid = table2.tripid)
where exists
(select pattern from table2 where table1.tripid = table2.tripid);
commit;
select * from table1;
returns:
Table dropped.
Table created.
1 row created.
1 row created.
1 row created.
1 row created.
1 row created.
Table dropped.
Table created.
1 row created.
1 row created.
Commit complete.
TRIPID PATTERN
---------- -------
1 A
1 A
1 A
2 B
2 B
5 rows selected.
5 rows updated.
TRIPID SEQUENCE PATTERN
---------- ---------- -------
1 1 A
1 2 A
1 3 A
2 1 B
2 2 B
5 rows selected.
Which proves that with good data, Oracle (and your query) works perfectly.
Christian