Delete values in one table based on values in another table - mysql

I was trying to execute this statement to delete records from the F30026 table that followed the rules listed.. I'm able to run a select * from and a select count(*) from with that statement, but when running it with a delete it doesn't like it.. it gets lost on the 'a' that is to define F30026 as table a
delete from CRPDTA.F30026 a
where exists (
select b.IMLITM from CRPDTA.F4101 b
where a.IELITM=b.IMLITM
and substring(b.IMGLPT,1,2) not in ('FG','IN','RM'));
Thanks!

This looks like an inner join to me, see MySQL - DELETE Syntax
delete a from CRPDTA.F30026 as a
inner join CRPDTA.F4101 as b on a.IELITM = b.IMLITM
where substring(b.IMGLPT, 1, 2) not in ('FG', 'IN', 'RM')
Please note the alias syntax as a and as b.

Instead of the 'exists' function, you can match the id (like you do in the where clause):
delete from CRPDTA.F30026 a
where a.IELITM IN (
select b.IMLITM from CRPDTA.F4101 b
where a.IELITM=b.IMLITM
and substring(b.IMGLPT,1,2) not in ('FG','IN','RM'));

I believe this is what you really want, all IELITMs which meet your criteria.
delete from CRPDTA.F30026
where IELITM IN (
select IMLITM from CRPDTA.F4101
where substring(IMGLPT,1,2) not in ('FG','IN','RM'));

Related

Sql Select a minimum value from a table column and insert the results in another table column in one SQL statement

I am trying to get a minimum value from the Candidate table and insert that value in the MinTotal table. Can you do both in one SQL statement?
Here's my SQL Statement:
UPDATE MinTotal SET MinTotal.min_total= MIN(CandidateID.TotalVotes);
UPDATE MinTotal a
INNER JOIN (SELECT MIN(c.TotalVotes) min_vote, c.CandidateID FROM Candidate c
GROUP BY c.CandidateID) b ON b.CandidateID = a.CandidateID
SET a.min_total = b.min_vote;
Try the above. This is specific for each candidate, else you can use the other answers provided.
You have to use a select so you can properly set your MIN().
One way of doing that would be like that:
UPDATE MinTotal
SET
min_total = Cmin.minresult
FROM (
SELECT MIN(TotalVotes) as minresult
from CandidateID
) Cmin
In general, that would be one way to solve the Problem. In this case you would set the minresult for every row you have in your MinTotal table. If you dont want that, you may need to be more specific about your desired output and add some examples in your question
UPDATE MinTotal
SET MinTotal.min_total = (
SELECT MIN(TotalVotes)
FROM CandidateID
);

Why this SQL DELETE query using another query output as WHERE condition go into error?

I am not so into SQL and I have the following problem. I am using MySql
I have a table named Market_Commodity_Price_Series and I have to delete some records from this table using a query output as WHERE condition, so I have done something like this:
DELETE FROM Market_Commodity_Price_Series
WHERE Market_Commodity_Price_Series.id = (SELECT MCPS.id
FROM Market_Commodity_Price_Series as MCPS
WHERE
month(MCPS.price_date) > 3
AND
year(MCPS.price_date) = 2018)
This query
(SELECT MCPS.id
FROM Market_Commodity_Price_Series as MCPS
WHERE
month(MCPS.price_date) > 3
AND
year(MCPS.price_date) = 2018)
return n ID that identifies the record that have to be deleted.
The problem is that performing this delete query I obtain this error message:
HY000You can't specify target table 'Market_Commodity_Price_Series' for update in FROM clause
Why? What is the problem? What am I missing? How can I fix this issue?
Sorry,
it was absolutly simple task:
DELETE FROM Market_Commodity_Price_Series
WHERE MONTH(price_date) > 3 AND YEAR(price_date) = 2018
Try the below query
DELETE FROM Market_Commodity_Price_Series WHERE Market_Commodity_Price_Series.id = (SELECT * FROM(SELECT MCPS.id FROM Market_Commodity_Price_Series as MCPS WHERE month(MCPS.price_date) > 3 AND year(MCPS.price_date) = 2018)tblTmp);
The query is basically the same, except the inner select is wrapped inside another select.
The most important thing to note is that the original select has been given an alias “tblTmp“. (The name tblTmp is arbitrary, you can give it any alias name.)
The alias is important because assigning one will tell MySQL to create a temporary table from this select query.
The temporary table may then be used as the source criteria for the update statement.
The reason it is wrapped inside another query is because MySQL syntax does not let you assign an alias to a select query when it is part of an update statement.
So we have to put it inside another query which, I suppose separates it from the update statement.
Not sure but I think it should be
DELETE * FROM Market_Commodity_Price_Series
WHERE [...]

subquery in where clause of UPDATE statement

I have the database of ATM card in which there are fields account_no,card_no,is_blocked,is_activated,issue_date
Fields account number and card numbers are not unique as old card will be expired and marked as is_block=Y and another record with same card number ,account number will be inserted into new row with is_blocked=N . Now i need to update is_blocked/is_activated with help of issue_date i.e
UPDATE card_info set is_blocked='Y' where card_no='6396163270002509'
AND opening_date=(SELECT MAX(opening_date) FROM card_info WHERE card_no='6396163270002509')
but is doesn't allow me to do so
it throws following error
1093 - You can't specify target table 'card_info' for update in FROM clause
Try this instead:
UPDATE card_info ci
INNER JOIN
(
SELECT card_no, MAX(opening_date) MaxOpeningDate
FROM card_info
GROUP BY card_no
) cm ON ci.card_no = cm.card_no AND ci.opening_date = cm.MaxOpeningDate
SET ci.is_blocked='Y'
WHERE ci.card_no = '6396163270002509'
That's one of those stupid limitations of the MySQL parser. The usual way to solve this is to use a JOIN query as Mahmoud has shown.
The (at least to me) surprising part is that it really seems a parser problem, not a problem of the engine itself because if you wrap the sub-select into a derived table, this does work:
UPDATE card_info
SET is_blocked='Y'
WHERE card_no = '6396163270002509'
AND opening_date = ( select max_date
from (
SELECT MAX(opening_date) as_max_date
FROM card_info
WHERE card_no='6396163270002509') t
)

strange mysql error

i have 2 queries:
UPDATE dws_photogallery_albums a
SET a.photoscount=(
SELECT COUNT(*) FROM dws_photogallery_photos p
WHERE p.albumid=a.albumid)
UPDATE dws_photoportfolio_photos a
SET a.photoscount=(
SELECT COUNT(*) FROM dws_photoportfolio_photos p
WHERE p.albumid=a.albumid)
first works ok, but second gives me error:
#1093 - You can't specify target table 'a' for update in FROM clause
Tables are identical (differs only by name).
what can it be?
UPD: Men, i'm so sorry, it's just my missprint, queries must be like that:
UPDATE dws_photogallery_albums a
SET a.photoscount=(
SELECT COUNT(*) FROM dws_photogallery_photos p
WHERE p.albumid=a.albumid)
UPDATE dws_photoportfolio_albums a
SET a.photoscount=(
SELECT COUNT(*) FROM dws_photoportfolio_photos p
WHERE p.albumid=a.albumid)
And they both works ok for me.
Thanks for answers, need more coffee
It means, that you can't update the table you are reading from. Aliases won't solve the problem. It could lead to inconsistencies. You have to work with temporary tables or in your case with variables.
you are updating same table that you use in nested select.
you can't do this:
update table X
where ... ( Select ... from X )
It is not strange You can't specify target table for update in FROM clause.
Notice that you are having the same table for update and select in second query
Try this query -
UPDATE
dws_photoportfolio_photos a
JOIN (
SELECT albumid, COUNT(*) cnt FROM dws_photoportfolio_photos GROUP BY albumid
) p
ON p.albumid = a.albumid
SET a.photoscount = p.cnt;

sql query for deleting rows with NOT IN using 2 columns

I have a table with a composite key composed of 2 columns, say Name and ID. I have some service that gets me the keys (name, id combination) of the rows to keep, the rest i need to delete. If it was with only 1 row , I could use
delete from table_name where name not in (list_of_valid_names)
but how do I make the query so that I can say something like
name not in (valid_names) and id not in(valid_ids)
// this wont work since they separately dont identity a unique record or will it?
Use mysql's special "multiple value" in syntax:
delete from table_name
where (name, id) not in (select name, id from some_table where some_condition);
If your list is a literal list, you can still use this approach:
delete from table_name
where (name, id) not in (select 'john', 1 union select 'sally', 2);
Actually, no I retract my comment about needing special juice or being stuck with (AND OR'ing all your options).
Since you have a list of values of what you want to retain, dump that into a temporary table. Then do a delete against the base table for what does not exist in the temporary table (left outer join). I suck at mysql syntax or I'd cobble together your query. Psuedocode is approximate
DELETE
B
FROM
BASE B
LEFT OUTER JOIN
#RETAIN R
ON R.key1 = B.key1
AND R.key2 = B.key
WHERE
R.key1 IS NULL
The NOT EXISTS version:
DELETE
b
FROM
BaseTable b
WHERE
NOT EXISTS
( SELECT
*
FROM
RetainTable r
WHERE
(r.key1, r.key2) = (b.key1, b.key2)
)