Reputation: 79
I need to find out how to delete records based on subquery.
I've tried a lot of things and scoured here so as to not duplicate the question, but couldn't find an answer.
Here is the subquery:
SELECT TOP (100) PERCENT t.id_col, t.dept_no, t.unit, t.lease_star
FROM trans AS t FULL OUTER JOIN
temp_lease AS l ON t.dept_no = l.dept_no AND t.unit = l.unit AND t.lease_star = l.lease_start_date
WHERE (l.dept_no IS NULL)
ORDER BY t.dept_no, t.unit, t.lease_star
The subquery finds records in the trans file that do not have a matching combination of dept_no, unit, and lease_start_date (the two files have different names for the last field, as VFP truncates field names down to 10 -- and they upsized a VFP file).
Having found those records (and it does), I then want to be able to DELETE the records that don't have that triple match in the temp_lease table.
To begin with, I would want to SELECT instead of DELETE, as I always learned to only use a DELETE once you're assured of the correct code.
Can anyone help me solve this one out? I've tried every variation nothing seems to work.
Upvotes: 1
Views: 4259
Reputation: 1269443
Based on your description, I would use not exists
. To get the rows to delete:
SELECT t.*
FROM trans t
WHERE NOT EXISTS (SELECT 1
FROM temp_lease l
WHERE t.dept_no = l.dept_no AND
t.unit = l.unit AND
t.lease_start = l.lease_start_date
);
Deleting the records requires just a tweak to the query:
DELETE t
FROM trans t
WHERE NOT EXISTS (SELECT 1
FROM temp_lease l
WHERE t.dept_no = l.dept_no AND
t.unit = l.unit AND
t.lease_start = l.lease_start_date
);
A full join
is basically never useful in a delete
. You need a record in the first table in order to delete it. Hence, a left join
is sufficient.
Also, the above does not consider two columns to match when both are NULL
. If that is an issue, you can tweak to the correlation clause to handle NULL
values.
Upvotes: 1
Reputation: 40
DELETE FROM trans WHERE id_col in( SELECT TOP (100) PERCENT t.id_col FROM trans AS t FULL OUTER JOIN temp_lease AS l ON t.dept_no = l.dept_no AND t.unit = l.unit AND t.lease_star = l.lease_start_date WHERE (l.dept_no IS NULL) ORDER BY t.dept_no, t.unit, t.lease_star) innerquery
--Inner query - it run faster
DELETE FROM trans
WHERE id_col in([ID_LIST_FROM_1st_QUERY])
Hope it helps.
Upvotes: 0
Reputation: 727
You could do something like this:
DELETE FROM trans
WHERE id_col in(
SELECT TOP (100) PERCENT t.id_col
FROM trans AS t FULL OUTER JOIN
temp_lease AS l ON t.dept_no = l.dept_no AND t.unit = l.unit AND t.lease_star = l.lease_start_date
WHERE (l.dept_no IS NULL)
ORDER BY t.dept_no, t.unit, t.lease_star) innerquery
If you insist on doing a SELECT FIRST, you could run the inner query first, and later do this:
DELETE FROM trans
WHERE id_col in([ID_LIST_FROM_1st_QUERY])
I'd go with the first though, because after you have tested enough is fine if you delete what you don't need (and having them separated will delete anyway).
Hope it helps.
Upvotes: 1