Delete multiple rows - mysql

I want to delete all records in table participant_vote where the id matches the id of another table row.
Can this be done in one query?
This is the query I have now which returns the error that my subselect contains multiple rows
DELETE FROM participant_vote WHERE id = (SELECT id FROM vote WHERE
facebookid = :facebookid)

DELETE FROM participant_vote WHERE id IN (SELECT id FROM vote WHERE facebookid = :facebookid)
IN being the trick. My feeling is that searching for the message would also have provided an answer.

Yes. Use the IN operator instead of the = operator.
DELETE FROM participant_vote
WHERE id IN (
SELECT id
FROM vote
WHERE facebookid = :facebookid
)

Related

Having multiple statements on where clause with same column name

I have a sample SQL statement that says:
SELECT * from users WHERE id = 2 OR id = 5 OR id = 7
What I would like is to avoid repeating id each time in the where clause. Is there a shortcut for this in MySQL that will allow me to mention the id only once?
Yes, the IN clause
SELECT * from users WHERE id IN(2,5,7);
if these Ids you are using in the comparison come from another table you can even do
SELECT * FROM users WHERE id in (SELECT other_id FROM other_table WHERE somecondition)
e4c5 gave you the answer you needed, but here is something else you can do with IN:
select * from users where 'steve' IN (users.fname, users.lname)

How that a row exists with specific values in MySQL

I've got a table looking like:
productId uid version
I just want to know if a row with specific values exists, I don't need any data returned.
How to do this?
Try this:
SELECT EXISTS(SELECT * FROM tablename WHERE productId=210)
A simple one is;
SELECT EXISTS (
SELECT uid FROM my_table
WHERE product_id = <product id to check for>
AND uid = <uid to check for>
AND version = <version to check for>
) does_exist;
An SQLfiddle to test with.
It will return 1 if the row exists, 0 if it doesn't.
You can also do it with COUNT;
SELECT COUNT(*) how_many_exist
FROM my_table
WHERE product_id = <product id to check for>
AND uid = <uid to check for>
AND version = <version to check for>
...but this will most likely be slower, since EXISTS only needs to find a single row to return 1, while COUNT needs to do work on finding all matching rows (even if only one exists) to count them.
SELECT COUNT(*) FROM product_table where productId =2
if the result is > 0 then product with id 2 exist otherwise doesn't

Combine Update and Select Query

I got two MySQL working fine and i'm trying to find a way to combine them into one single query.
First, it selects ID of an employee.
SELECT 'ID' FROM `employee` ORDER BY ID DESC LIMIT 1;
Let's say it returns ID 100;
Then update data of employees whose ID is 100
UPDATE 'LOG' SET `TIME_EXIT`='2013/02/22' WHERE `ID`='100';
Can i do it all in a single query?
Just add them together:
UPDATE LOG SET TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM employee
ORDER BY ID DESC
LIMIT
);
But based on that code currently it'll only ever update the last employee, you will need to select the correct employee by using some other identifier to ensure you have the correct one.
UPDATE LOG SET TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM employee
WHERE NAME = 'JOHN SMITH'
ORDER BY ID DESC
LIMIT 1
);
It's now a few months old, but maybe helps you or others finding this via google…
If you want to UPDATE a field in the same selected table use this:
UPDATE LOG SET
TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM (
SELECT ID
FROM LOG
WHERE whatEverYouWantToCheck = whateverYouNeed
) AS innerResult
)
So, you SELECT id from a subselect. If you try to subselect it directly, mySQL quites with your error message You can't specify target table 'log' for update in FROM clause, but this way you hide your subsubquery in a subquery and that seems to be fine. Don't forget the AS innerResult to avoid getting the error message #1248 - Every derived table must have its own alias. Also match the subsubquery field name to the subquery field name in case you do something like SELECT COUNT(*) or SELECT CONCAT('#', ID)

DELETE FROM for entries with same id, but leave the last one in the table

I have a table that contains
id username password last_touch
It is possible to have duplicate entries for the same id. The last_touch is the timestamp of the last insert command. How can I delete all entries with the same id, apart from the last one that is left so I always have the user details which are most up to date?
Somewhere along the lines of:
DELETE FROM user_data
WHERE id=1
LIMIT (count(SELECT 1
FROM user_data
WHERE id=1) - 1)
(Obviously the syntax is not correct in the above example, so MySQL complains.)
Use a nested query to select the latest timestamp for the given user id, and delete all rows for that id with timestamps different than that one:
DELETE FROM user_data
WHERE ID = 1 AND last_touch !=
(SELECT latest FROM
(SELECT MAX(last_touch) AS latest FROM user_data WHERE ID = 1) AS temp
)
Update: Fixed direct reference to table being modified in inner SELECT by wrapping another SELECT around it, as per Frank's comments.
DELETE FROM user_data u
WHERE id=1
AND last_touch < (SELECT max(last_touch)
FROM user_data
WHERE id=u.id)

MySQL - How can I update a table with values from another table?

I have the task to repair some invalid data in a mysql-database. In one table there are people with a missing date, which should be filled from a second table, if there is a corresponding entry.
TablePeople: ID, MissingDate, ...
TableEvent: ID, people_id, replacementDate, ...
Update TablePeople
set missingdate = (select replacementDate
from TableEvent
where people_id = TablePeople.ID)
where missingdate is null
and (select count(*)
from TableEvent
where people_id = TablePeople.ID) > 0
Certainly doesn't work. Is there any other way with SQL? Or how can I process single rows in mysql to get it done?
We need details about what's not working, but I think you only need to use:
UPDATE TablePeople
SET missingdate = (SELECT MAX(te.replacementDate)
FROM TABLEEVENT te
WHERE te.people_id = TablePeople.id)
WHERE missingdate IS NULL
Notes
MAX is being used to return the latest replacementdate, out of fear of risk that you're getting multiple values from the subquery
If there's no supporting record in TABLEEVENT, it will return null so there's no change