Delete data comparing two tables - sql

I have two tables: Table A and Table B. Both tables have a column like a Name, Location, Level. Table A is an initial table and Table B is the updated version of Table A. That means there will be new data present in Table B. I want to write a query that deletes the data from Table B if data is present in Table A but not in Table B. I don't want to delete the data from Table B if the table has a new row of data.
My approach was like this
Delete From TableB Where Exist(
SELECT * FROM dbo.TableB AS TB
EXCEPT
SELECT * FROM dbo.TableA as TA)
This one deletes the data, but it deletes the data from Table B if it is new inserted data as well. Any kind of suggestion is appreciated.

DELETE FROM TableB
WHERE EXIST(
SELECT 1
FROM TableA
WHERE TableA.Name = Name AND TableA.Location = Location AND TableA.Level = Level
)
If TableA has a primary key, then it's enough to check only this key in WHERE condition. Furthermore, if you have this primary key (e.g. it's Name), then you can do like this:
DELETE FROM TableB
WHERE Name IN (SELECT Name FROM TableA)

Related

SQL Update, update inserted data from table

I'm not sure whether my approach is correct or not. I have two table, A and B. I need to create ID on table A then the details on table B. Column ID in table A is auto incremented.
INSERT INTO TABLE A (DESCRIPTION)
SELECT REPLACE(DESCRIPTION, 100, #INCREMENT)
FROM TABLE A
Now I have created the ID in table A, I need to create new row on table B based on EXISTING data on table B. Below is my query.
INSERT INTO TABLE B (ID, JOBCODE)
SELECT ID, JOBCODE
FROM TABLE B INNER JOIN TABLE A ON A.ID = B.ID
How do I update the recently created row on table B so it match the ID on table A.

Insert new/Changes from one table to another in Oracle SQL

I have two tables with same number of columns :-Table A and Table B
Every day I insert data from Table B to Table A. now the insert query is working
insert into table_a (select * from table_b);
But by this insert the same data which was inserted earlier that is also getting inserted. I only want those rows which are new or are changed from the old data. How can this be done ?
You can use minus:
insert into table_a
select *
from table_b
minus
select *
from table_a;
This assumes that by "duplicate" you mean that all the columns are duplicated.
If you have a timestamp field, you could use it to limit the records to those created after the last copy.
Another option is, assuming that you have an primary key (id column in my example) that you can use to know whether a record has already been copied, you can create a table c (with the same structure as a and b) and do the following:
insert into table c
select a.* from table a
left join table b on (a.id=b.id)
where b.id is null;
insert into table b select * from table c;
truncate table c;
You need to adjust this query in order to use the actual primary key.
Hope this helps!
If the tables have a primary or unique key, then you could leverage that in an anti-join:
insert into table_a
select *
from table_b b
where not exists (
select null
from table_a a
where
a.pk_field_1 = b.pk_field_1 and
a.pk_field_2 = b.pk_field_2
)
You don't say what your key is. Assuming you have a key ID, that is you only want ID's that are not already in Table A. You can also use Merge-Statement for this:
MERGE INTO A USING B ON (A.ID = B.ID)
WHEN NOT MATCHED THEN INSERT (... columns of A) VALUES (... columns of B)

populate many to many table from existing tables

I have two existing tables with data populated
table A
--tableA_id
--contentA
table B
--tableB_id
--contentB
Now, I want to create a many to many relationship table
table A_B
--tableA_id
--tableB_id
the question is that how to write a sql script (I am new to sql) to populate table A_B using the existing data from table A and table B. Many thanks,
Mark
If you want to populate table A_B, you'd have to do this:
INSERT INTO A_B (tableA_id, tableB_id)
SELECT A.ID, B.ID FROM A CROSS JOIN B
CROSS JOIN will relate each row in table A with each row in table B.
If you want to relate some rows in table A with some rows in table B, you need to be more specific, and do something like:
INSERT INTO A_B (tableA_id, tableB_id)
SELECT A.ID, B.ID FROM A INNER JOIN B
ON A.some_field = B.some_other_field

Update query to get new records without a unique key?

I have a table of accounting transactions and I am trying to copy them into a new table. I have the copy worked out, but I need to update the copy with any new transactions from my source table. The problem I have is that the source data is coming from a report that links many different sources to create these transactions and doesn't have a unique key.
If I had a unique key, I would create an update query and do a left join from the source table to the copied table and anytime the key is null in the copied table, update those fields.
Since I don't have a unique key, I don't know how to accomplish this. Any ideas?
-----Edit due to Answers-----
SourceTable
Field1 Field2 Field3
CopiedTable
Field1 Field2 Field3
So to update CopiedTable with new records I would do this??
UPDATE CopiedTable SET
CopiedTable.Field1 = SourceTable.Field1,
CopiedTable.Field2 = SourceTable.Field2,
CopiedTable.Field3 = SourceTable.Field3
WHERE (SourceTable.Field1 <> CopiedTable.Field1 AND
SourceTable.Field2 <> CopiedTable.Field2 AND
SourceTable.Field3 <> CopiedTable.Field3)
It is difficult to answer the question without seeing the source tables, the destination table and the query.
Use a compound key consisting of all the unique key fields of the different tables.
EDIT:
Every table must have a primary key. This is a basic design rule for databases. Let us assume that you have two source tables A and B
Table A
-------
A_ID, DataField1, DataField2
Table B (lined to Table A through A_ID)
-------
B_ID, A_ID, DataField3, DataField4
Now you can create table C like this
SELECT
CLng(A.A_ID) AS A_ID, CLng(B.B_ID) AS B_ID,
A.DataField1, A.DataField2, B.DataField3, B.DataField4
INTO
C
FROM
A INNER JOIN B ON A.A_ID = B.A_ID;
I would make A_ID and B_ID a primary key in C.
If A_ID and B_ID are AutoNumbers we need to do a trick with CLng in order to create regular number fields in C.
If later we want to refill C with fresh data from A and B, we can do
DELETE * FROM C;
INSERT INTO C
(A_ID, B_ID, DataField1, DataField2, DataField3, DataField4)
SELECT
A.A_ID, B.B_ID, A.DataField1, A.DataField2, B.DataField3, B.DataField4
FROM
A INNER JOIN B ON A.A_ID = B.A_ID;
If we want to update only changed records, we need to link the source with the copy and, in addition, test if we have changes in the WHERE clause
UPDATE
C
INNER JOIN (SELECT
A.A_ID, B.B_ID,
A.DataField1, A.DataField2, B.DataField3, B.DataField4
FROM
A INNER JOIN B ON A.A_ID = B.A_ID) AS Src
ON C.B_ID = Src.B_ID AND C.A_ID = Src.A_ID
SET
C.DataField1 = Src.DataField1,
C.DataField2 = Src.DataField2,
C.DataField3 = Src.DataField3,
C.DataField4 = Src.DataField4
WHERE
C.DataField1<>Src.DataField1 OR
C.DataField2<>Src.DataField2 OR
C.DataField3<>Src.DataField3 OR
C.DataField4<>Src.DataField4;
The sub-select Src could be another stored query.

SQL Select Into Field

I want to accomplish something of the following:
Select DISTINCT(tableA.column) INTO tableB.column FROM tableA
The goal would be to select a distinct data set and then insert that data into a specific column of a new table.
SELECT column INTO tableB FROM tableA
SELECT INTO will create a table as it inserts new records into it. If that is not what you want (if tableB already exists), then you will need to do something like this:
INSERT INTO tableB (
column
)
SELECT DISTINCT
column
FROM tableA
Remember that if tableb has more columns that just the one, you will need to list the columns you will be inserted into (like I have done in my example).
You're pretty much there.
SELECT DISTINCT column INTO tableB FROM tableA
It's going to insert into whatever column(s) are specified in the select list, so you would need to alias your select values if you need to insert into columns of tableB that aren't in tableA.
SELECT INTO
Try the following...
INSERT INTO tableB (column)
Select DISTINCT(tableA.column)
FROM tableA
The goal would be to select a distinct data set and then insert that data into a specific column of a new table.
I don't know what the schema of tableB is... if table B already exists and there is no unique constraint on the column you can do as any of the others suggest here....
INSERT INTO tableB (column)Select DISTINCT(tableA.column)FROM tableA
but if you have a unique constraint on table B and it already exists you'll have to exclude those values already in table B...
INSERT INTO tableB (column)
Select DISTINCT(tableA.column)
FROM tableA
WHERE tableA.column NOT IN (SELECT /* NOTE */ tableB.column FROM tableB)
-- NOTE: Remember if there is a unique constraint you don't need the more
-- costly form of a "SELECT DISTICT" in this subquery against tableB
-- This could be done in a number of different ways - this is just
-- one version. Best version will depend on size of data in each table,
-- indexes available, etc. Always prototype different ways and measure perf.