I have a simple enough query that will be used as part of a SP to clean the database from time to time. TableA and TableB are related with a ID. I build a table variable with all the IDs in TableA and then delete all the one that appear in TableB. This sintax works just fine:
DELETE #TableIds
FROM #TableIds AS tids
WHERE tids.sharedID IN (SELECT tb.sharedID FROM TableB AS tb WITH (nolock))
How can this query be done with a JOIN instead of a IN (subquery)?
You don't need a table variable to do this. Use delete with a join so the matched id records can be deleted.
delete a
from tablea a
join tableb b on a.id=b.id
Try like below
DELETE Tids
FROM #TableIds AS tids
INNER JOIN TABLEb TB(Nolock) ON TIDS.SHAREID= TB.SHAREId
Related
I face issue about duplicate data when join table, here my sample data table I have
-- Table A
I want to join with
-- Table B
this my query notation for join both table,
select a.trans_id, name
from tableA a
inner join tableB b
on a.ID_Trans = b.trans_id
and this the result, why I get the duplicating data which should show only two lines of data, please help me to solve this case.
Firstly, as you have been told multiple times in the comments, this is working exactly as you have written, and (more importantly) as intended. You have 2 rows in tableA and those 2 rows match 2 rows in your table tableB according to the ON clause. This means that each join operation, for the each of the rows in tableA, results in 2 rows as well; thus 4 rows (2 * 2 = 4).
Considering that your table, TableA only has one column then it seems that you should be cleaning up that data and deleting the duplicates. There are plenty of examples on how to do that already (example).
Perhaps the column you show us in TableA is one many, and thus instead you have a denormalisation issue, and instead there should be another table with the details of Id_trans and a PRIMARY KEY or UNIQUE CONSTRAINT/INDEX on it. Then you would join fron that table to TableB.
Finally, what you might be after is an EXISTS, which would look like this:
SELECT B.trans_id, B.[name]
FROM dbo.TableB B
WHERE EXISTS(SELECT 1
FROM dbo.TableA A
WHERE A.ID_Trans = B.trans_id); --Odd that it's called ID_Trans in one table, and Trans_ID in another
As the comments mentioned your query does exactly what you asked it to do but I think you wanted something like:
select a.trans_id, a.name, b.name
from tableA a
inner join tableB b on a.trans_id = b.trans_id
group by a.trans_id, a.name, b.name
Since there are two rows in both table with same ID join will make them four. You can use distinct to remove duplicates:
select distinct a.trans_id, name
from tableA a
inner join tableB b
on a.id_trans = b.trans_id
But I would suggest to use exists:
select trans_id, name
from tableB b
exists (select 1 from tableA a where a.trans_id=b.trans_id)
I am seriously suffering from brain dead as I have done this successfully several times in the past.
This time, it isn't working.
I have 2 tables, tableA and tableB
TableA has all the surmons records
TableB has some but not all surmons.
The common key between them is surmonId.
The requirement is to display the surmons from tableB where there is a match between tableA and tableB but at the same time, display ALL the surmons from tableA.
In other words, give me from tableB any records that exist and all the records on tableA.
The lef join query below is only giving me records that exist in tableB.
Select distinct l.surmons from tableB b left join tableA a on b.surmonId = a.surmonId.
There are only 10 surmons on tableB and that's all I am getting.
Where am I messing up?
Thanks a lot in advance
Either switch order of your tables:
SELECT DISTINCT a.surmons
FROM tableA a
LEFT JOIN tableB b
ON a.surmonId = b.surmonId
Or use my favorite, the RIGHT JOIN:
SELECT DISTINCT a.surmons
FROM tableB b
RIGHT JOIN tableA a
ON b.surmonId = a.surmonId
If you want everything from tableA, you need to make the left join from tableA to tableB.
Select distinct a.surmons from tableA a left join tableB b on a.surmonId = b.surmonId
I am trying to join 2 tables together and do a delete on it.
DELETE TableA
FROM TableA a
INNER JOIN
TableB b on b.Id = a.Id
where title like 'test'
The above is what I come up with however I keep getting
The DELETE statement conflicted with the REFERENCE constraint
I thought if I merge the 2 tables together then I will delete both at the same time and no constraints would be conflicted.
Am I missing something in my query?
try this:
DELETE TableA
FROM TableA
INNER JOIN
TableB b on b.Id = TableA.Id
where TableA.title like 'test'
First try to delete TableB with that title condition
Then delete those records in TableA
DELETE FROM TableB
WHERE Id IN
( SELECT Id FROM TableA WHERE title = 'test')
DELETE FROM TableA
WHERE title = 'test'
Referential Constraints blocks you from deleting rows in TableA when you still have reference in TableB
I would delete one after the other with cascade constraint.
I have a table in an Access database where records may be referenced from either of two other tables. I need to delete records from that table if they are not referenced by either of the others.
My best solution so far has been to create a subquery to return the id's of the referenced records and to refer to the subquery from a delete query. (The subquery has to be separate because Access does not allow UNION in nested subqueries.)
So ...
SelectQuery:
SELECT TableB.id FROM TableB INNER JOIN TableA ON TableB.id = TableA.id
UNION
SELECT TableC.id FROM TableC INNER JOIN TableA ON TableC.id = TableA.id
DeleteQuery:
DELETE * FROM TableA WHERE id NOT IN (SELECT * FROM SelectQuery)
This is excruciatingly slow ... there must be a better way?
I was trying to avoid having to add a boolean 'Used' field to TableA ...
#Matthew PK suggests using two NOT IN subqueries, which is theoretically a good idea, but as I observed in a comment, NOT IN and NOT EXISTS are poorly optimized by Jet/ACE and will often not use the indexes on both sides of the comparison. I'm wondering whether or not subqueries are necessary or not:
DELETE *
FROM (TableA LEFT JOIN TableB ON TableA.ID = TableB.ID) LEFT JOIN TableC ON TableA.ID = TableC.ID
WHERE TableB.ID Is Null AND TableC.ID Is Null;
This would definitely use your indexes. If a subquery is necessary, you could replace TableB and TableC with the relevant subqueries.
Why not something like this:
DELETE FROM TableA
WHERE
id NOT IN (SELECT id FROM TableB)
AND
id NOT IN (SELECT id FROM TableC)
?
Is it acceptable to create a new table based on your SelectQuery, delete the original table, and rename the new one to the original name?
/* delete more records */
DELETE FROM table1
WHERE NOT EXISTS
(SELECT field FROM table2 WHERE table2.field = table1.field)
It is possible to delete records based on a satisfied condition with a join query?
For instance, I have a linking table joining 3 records. The query I have at the moment deletes records from this table where one of the id's isn't IN() an imploded Php array. I've come to realise that the query should only remove records from this table if the id's don't exist in the array and they belong to a certain other table based on the a link to another table.
For SQL Server, the command is slightly different:
DELETE FROM TableA
FROM TableA LEFT OUTER JOIN TableB ON TableA.Column = TableB.Column
WHERE TableB.Column IS NULL
No, that's not a typo, yes, you do need "FROM TableA" twice. At least, you need the second FROM (the first is optional). The following has the advantage that it works for both SQL Server and MySQL:
DELETE TableA
FROM TableA LEFT OUTER JOIN TableB ON TableA.Column = TableB.Column
WHERE TableB.Column IS NULL
I like to use EXISTS clauses for this:
DELETE FROM TableA
WHERE
<<put your array condition here>>
AND NOT EXISTS
(SELECT 1 FROM TableB Where TableB.ID=TableA.ID)
You can use :
DELETE Based on a Join:
DELETE A
FROM TableA AS A
LEFT OUTER JOIN TableB As B ON A.Id = B.TabaleAId
WHERE B.Column IS NULL
Delete With SubQuery:
DELETE
FROM TableA AS A
Where
A.id not in ( Select B.TabaleAId From Tab;eB As B )
or
DELETE FROM TableA
WHERE Not EXISTS
(
SELECT *
FROM TableB As B
Where B.TableAId = TableA.Id
)
DELETE Using Table Expressions:
With A
As
(
Select TableA.*
FROM TableA AS A
LEFT OUTER JOIN TableB As B ON A.Id = B.TabaleAId
WHERE B.Column IS NULL
)
Delete From A
DELETE FROM TableA
LEFT OUTER JOIN TableB
WHERE TableB.Column IS NULL
Will delete the records in tableA that don't have a corresponding record in TableB. Is that like what you are after?
DELETE FROM a
FROM TableA AS a LEFT OUTER JOIN TableB AS b
on a.CALENDAR_DATE = b.CALENDAR_DATE AND a.ID = b.ID
Where b.ID is null
You can first use the select statement and verify your records that you want to delete and then remove the select statement and add Delete FROM tablename with the above query syntax.
The easiest way to Delete based on join is as follow:
1.Write your query using SELECT statement instead of DELETE statement
SELECT COLUMNS
FROM Table1
INNER JOIN Table2 ON Table1.YYY = Table2.XXX
2.Replace SELECT COLUMNS with DELETE FROM TABLE
DELETE FROM Table1
FROM Table1
INNER JOIN Table2 ON Table1.YYY = Table2.XXX
Note that we need to specify FROM twice, one for DELETE part and one for JOIN part.
delete from TableA
where id in
(
select id from TableA
except select id from TableB
)
Which means "delete from tableA where id in table a but not in table b)
Otherwise a Merge statement might help you (when matched/not matched delete etc)
http://technet.microsoft.com/en-us/library/bb510625.aspx