MySQL: DELETE FROM using a multi conditional "not equal to" WHERE - mysql

Hah. So. I've been playing with this particular query where I'm trying to delete a large swath of rows but I end up not doing what I'm expecting. I've run various variations of this query and I'm not having any luck.
Basically I'm trying to do this:
DELETE FROM table WHERE country <> 'MX' OR 'CA';
OR
DELETE FROM table WHERE foobar NOT IN ( 12 OR 5 );
OR
DELETE FROM table WHERE foobar NOT IN ( 'foo' ) OR ( 'bar' );
And a couple other ideas I had that weren't working. I'm just uploading a fresh dataset for the umpteenth time I'd appreciate some help in the right direction.

Actually, logical operators like "OR" are applied to conditions but not values.
So, you can use either
DELETE FROM table WHERE country <> 'MX' AND country <> 'CA';
or
DELETE FROM table WHERE country NOT IN ('MX', 'CA')
The second one is preferable.

Try this:
DELETE FROM table WHERE country NOT IN ('MX', 'CA');

Related

MySQL multi query in one

I have a table name user with user_id, image_id .... (and some others attribute)
Another table name image with image_id and image_name ...
I wanna search an image_id by image_name, and update to user table that image_id found
like this:
UPDATE person SET image_id = (
SELECT image_id
FROM image
WHERE image.src='02.jpg' ) WHERE person_id=2
Of course, it doesn't work. I just use that query to show you what i want.
I can use 2 queries on php code, the first get image_id, the second update it to table.
But I think there is a better way to do it.
The problem here might well be that the subselect is returning more than one row and you are trying to update only one row in the table person.
Try that:
UPDATE person SET image_id = ( SELECT distinct image_id FROM image WHERE image.src='02.jpg' ) WHERE person_id=2
Can we see the error?
I think its not right way to use the sub-query in main query, you can create trigger in MySQL database or if you would like to use by this way then:
UPDATE person
SET person.image_id = ( SELECT image_id
FROM image
WHERE image_name='02.jpg'
)
WHERE person.person_id=2
update person p set p.image_id=(select i.image_id from images i where i.src='02.jpg' limit 1 ) where p.person_id=2
step 1: use table alias ( p, i ) so your fieldnames are not ambiguously
step 2: use limit 1 on subselect -> get not more than 1 rows
Better solution is to use some logic on serverside (php/perl...) and work with two seperate querys
Hope it helps...
Thomas

mysql query works with some particular records only not with all of the data

first image of student_detail table,second is image of payment_detail table when i fire the query like
SELECT `student_detail`.`id`,
`student_detail`.`first_name`,
`student_detail`.`last_name`,
`student_detail`.`course`,
`payment_detail`.`id`,
`student_id`,
`inst_paid_date`,
`next_inst_date`,
`paid_installment`,
`next_installment_amount`
FROM `student_detail`,`payment_detail`
WHERE MONTH(`next_inst_date`)=MONTH(now())
AND `inst_paid_date`<`next_inst_date`
AND `student_detail`.`id`=`student_id`
AND `student_id`='10'
AND `inst_paid_date` in(select max(`inst_paid_date`) from `payment_detail`)
it do not give any result when records are present like second table but if i delete student id 8 and 9 it gives the result other wise not i cant get how it is conflict with other records when perticularly set the where condition with student_id=10. thanks in advanced
The reason is that you limit your inst_paid_date to the maximum value across the entire payment_detail table. Since this maximum value is for student id 9 when it is present, this conflicts with your filter on student id 10.
Try to add the same filter to your subquery like this:
WHERE
...
AND `student_id`='10'
AND `inst_paid_date` in (select max(`inst_paid_date`)
from `payment_detail`
where `student_id` = '10')
A more generic solution would be to turn the subquery into a correlated subquery. This requires an alias on the outer reference to the payment_detail table:
...
FROM `student_detail`,`payment_detail` as `PD`
WHERE MONTH(`next_inst_date`)=MONTH(now())
AND `inst_paid_date`<`next_inst_date`
AND `student_detail`.`id`=`student_id`
AND `PD`.`student_id`='10'
AND `inst_paid_date` in(select max(`inst_paid_date`)
from `payment_detail`
where `student_id` = `PD`.`student_id`)

Delete values in one table based on values in another table

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'));

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
)

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)
)