Possible to change these 2 SQL queries into 1? - mysql

Is it possible to change these 2 queries into 1?
Query #1:
UPDATE `pvdownloader`.`posts`
SET `exists` = 'y'
WHERE source = ANY (SELECT source FROM dbdownloader.posts)
AND `mangacount` = 0
AND NOT `exists` = 'm'
Query #2:
UPDATE `pvdownloader`.`posts`
SET `exists` = 'n'
WHERE `exists` = 'u'
AND `mangacount` = 0
I'm assuming it would be possible to make something like this with IF/ELSE but I can't figure out how to use it at all :<

Maybe something like this would work:
update
pvdownloader.posts
set
exists =
case
when source = any(select source from dbdownloader.posts) and mangacount = 0 and exists != 'm' then 'y'
when exists = 'u' and mangacount = 0 then 'n'
end
where
(source = any(select source from dbdownloader.posts) and mangacount = 0 and exists != 'm')
or
(exists = 'u' and mangacount = 0)
;
As #MostyMostacho suggested, I took the liberty of changing your logic to not have a double-negative.

Related

Select Case / Update one field based on another

Basically, I am trying to cleanse a database and have all file paths point to sample documents. I am reading from one column (extension), and then updating another column (filename) and making a change based on the extension. I also want a catch all. For example, if extension is DOC, then make the path "sample.doc"; if the extension is PDF, then make the path "sample.pdf", if unknown, then make the path "sample.txt".
I have this code working, but think it would be better served with a select/case loop:
select * from dbo.tsrecelec
UPDATE dbo.TSRECELEC
SET dbo.tsrecelec.reSID = '00+SampleWord.doc'
WHERE dbo.tsrecelec.reExtension = 'DOC'
UPDATE dbo.TSRECELEC
SET dbo.tsrecelec.reSID = '00+SampleWord.docx'
WHERE dbo.tsrecelec.reExtension = 'DOCX'
UPDATE dbo.TSRECELEC
SET dbo.tsrecelec.reSID = '00+SampleADOBE.pdf'
WHERE dbo.tsrecelec.reExtension = 'PDF'
In my NONE SQL brain, I was thinking something like this might work?
SELECT reSID, reExtension,
CASE
WHEN reExtension = 'DOC' THEN SET reSID = '00+SampleWord.doc'
WHEN dbo.tsrecelec.reExtension = 'DOCX' THEN SET dbo.tsrecelec.reSID = '00+SampleWord.docx'
ELSE dbo.tsrecelec.reSID = '00+SampleFile.txt'
END
FROM dbo.tsrecelec;
Any and all help is appreciated!
Three updates is fine, but you can phrase this as:
UPDATE dbo.TSRECELEC
SET reSID = (CASE WHEN reExtension = 'DOC'
THEN '00+SampleWord.doc'
WHEN reExtension = 'DOCX'
THEN '00+SampleWord.docx'
WHEN reExtension = 'PDF'
THEN '00+SampleADOBE.pdf'
END)
WHERE reExtension IN ('DOC', 'DOCX, 'PDF');
Try to use CASE...WHEN...THEN.... It's more performant if you are getting more extensions in the future:
UPDATE yourtable
SET col1 = (CASE WHEN col2 = 'extension you want'
THEN 'nameofyourfile.extension'
WHEN ...
THEN ...
END)
WHERE col2 IN ('extension1', 'extension2', 'extension3','...');

Toggle boolean in MySQL / Oracle Database

Update myTable SET field = 1 (if field = 0 or if field is null) where myid = 12345;
Update myTable SET field = 0 (if field = 1) where myid = 12345;
What is the best way to transform this Pseudocode in proper SQL for Oracle and MySQL?
You could simply use the modulo like this:
UPDATE myTable SET field = (field + 1) % 2 WHERE myId = 12345;
Due to the lack of a real boolean in both DBMS you need a case statement:
update myTable
set the_column = case when the_column = 1 then 0 else 1 end
where myId = 12345;
This assumes that the column never has different values than 0 and 1

MySQL update column which is a value in another column

This is my previous question related to the my query.
MySQL select column which is a value in another column
The problem is that want to do operations on the values extracted and store it back into the original db. I've tried using a update & case but am not able to achieve it.
update msisdn_table
CASE reason
WHEN 'NoAnswer' THEN (case when (NoAnswer>0) then update msisdn_table set NoAnswer = NoAnswer-1 end)
WHEN 'NetworkBusy' THEN (case when NetworkBusy>0 then update msisdn_table set NetworkBusy = NetworkBusy-1 end)
WHEN 'CallRejection' THEN (case when CallRejection>0 then update msisdn_table set CallRejection = CallRejection-1 end)
WHEN 'Unavailable' THEN (case when Unavailable>0 then update msisdn_table set Unavailable = Unavailable-1 end)
END
Any help?
Try it this way if you want to do it one statement
UPDATE msisdn_table
SET NoAnswer = IFNULL(IF(reason = 'NoAnswer',
NULLIF(NoAnswer, 0) - 1, NoAnswer), 0),
NetworkBusy = IFNULL(IF(reason = 'NetworkBusy',
NULLIF(NetworkBusy, 0) - 1, NetworkBusy), 0),
CallRejection = IFNULL(IF(reason = 'CallRejection',
NULLIF(CallRejection, 0) - 1, CallRejection), 0),
Unavailable = IFNULL(IF(reason = 'Unavailable',
NULLIF(Unavailable, 0) - 1, Unavailable), 0)
WHERE reason IN('NoAnswer', 'NetworkBusy', 'CallRejection', 'Unavailable');
Note:
I changed CASE with less verbose IF(), although if you like it better you can use it the same way.
This approach has one possible side effect as it always updates the column(s) either with a new or with old value. It may matter if for example you have a trigger defined on the table.
You want to apply a WHERE clause to make sure that rows with other reason codes are not affected
Here is SQLFiddle demo
update msisdn_table set NoAnswer = NoAnswer-1 where (NoAnswer>0) ;
update msisdn_table set NetworkBusy = NetworkBusy-1 where (NetworkBusy = NetworkBusy-1) ;
update msisdn_table set CallRejection = CallRejection-1 where (CallRejection>0) ;
update msisdn_table set 'Unavailable' = 'Unavailable'-1 where (Unavailable>0) ;

Set all rows except 1

I have a flag in my database called published, I set this to 1 for a published row. My question is , is there a way to set all other rows to 0 and set a particular row to 1 with just one query.
At the moment im using:
$db->query("UPDATE my_table SET published = '0'");
$db->query("UPDATE my_table SET published = '1' WHERE id = '$id'");
UPDATE my_table SET published = IF (id = $id,1,0);
Use a CASE Statement
UPDATE my_table
SET published = CASE
WHEN id = '$id' THEN 1
ELSE 0 END
In MySQL, there's no boolean type (conditions return an integer), so this works too :
UPDATE my_table
SET published = (id = $id);
id = $id returns 0 if $id is different than id, else 1.

Update Query based on condition

I would like to do the following.
Update a field based on the value of another field like
update table set if(fielda=1){fieldb=2 fieldc=3}else{fieldd=2 fielde=3}
I know this is not valid mysql but its the best way for me to describe the problem.
update table set
b = case when a = 1 then 2 else b end,
c = case when a = 1 then 3 else c end,
d = case when a = 1 then d else 2 end,
e = case when a = 1 then e else 3 end
edit
according to your comment try this:
update table set
datefield_a = case when field_a = 1 then now() else datefield_a end,
datefield_b = case when field_a <> 1 then now() else datefield_b end
I think this syntax will achieve the result you attempted to specify.
UPDATE mytable
SET fieldb = CASE WHEN fielda = 1 THEN 2 ELSE fieldb END
, fieldc = CASE WHEN fielda = 1 THEN 3 ELSE fieldc END
, fieldd = CASE WHEN fielda = 1 THEN fieldd ELSE 2 END
, fielde = CASE WHEN fielda = 1 THEN fielde ELSE 3 END
The "trick" here is that we are updating all four columns, but in some "cases", we are assigning the current value of the column back to the column, resulting in no real change to the column value. (Once you get your mind bent around that idea, it's pretty easy.)
With MySQL, we do have a handy IF function (not available in most other RDBMS) that we can use to abbreviate that a bit, and achieve the same thing:
UPDATE mytable
SET fieldb = IF(fielda = 1, 2, fieldb)
, fieldc = IF(fielda = 1, 3, fieldc)
, fieldd = IF(fielda = 1, fieldd, 2)
, fielde = IF(fielda = 1, fielde, 3)
The pain is that you still have to repeat that same conditional test multiple times.
A single scan through the table (like these statements do), and getting all those assignments done in one fell swoop is going to be faster (and more efficient) than breaking this up and doing the assignments piecemeal using multiple statements.