This might be a very stupid questions, but I am keen to know if anyone has any suggestions:
Single Table Delete Correct Query : delete from vehicle_owner where id=3;
Single Table Delete InCorrect Query : delete from vehicle_owner v where v.id=3
Mulitple Table Delete : delete v,s from vehicle v , category s where v.id=3 and v.id=s.id;
Qs 1: I was wondering that why 1st is right and why 2nd is incorrect. Basically I am looking for logical answers which explains why providing an alias in delete query is incorrect.
Qs 2: why we keep two alias names after 'DELETE' keyword for multiple delete. Anyways we are providing complete details in join condition. So why it is designed in such a way.
The second is incorrect because if you use an alias, the SQL statement is considered a version of the multi-table DELETE that just happens to have only one table specified. As such, it must follow the other rules of multi-table DELETE. There's no room in the syntax for single-table DELETE to specify an alias.
You don't need to have aliases, but you do need to specify which of the tables you are deleting from. So you list the tables, or their aliases, directly after the DELETE keyword. Otherwise, MySQL won't know whether to delete rows only from the first table (with the other tables being present to filter) or to delete from all tables, or some combination.
See: https://dev.mysql.com/doc/refman/5.5/en/delete.html
The full correct syntax for your second example would be:
delete v from vehicle_owner as v where v.id = 3
Once you've specified the alias, you need to also specify it in the delete clause.
For your second question, I'm not quite sure what you're asking.
Related
I have an sql query that finds and groups these duplicates using very complicated conditions:
SELECT right(post_url, LOCATE('-', REVERSE(post_url),LOCATE('-',REVERSE(post_url))+1) -1) as name,
left(post_name,LOCATE('-',post_url,LOCATE('-',post_url)+1) - 1) as city,
post_title as original,ID,post_name,count(*)
FROM table WHERE post_type='finder'
GROUP BY name,city having count(*) > 1
To explain the query, post_url is basically a url name, ending with the name of someone, e.g : new-jersey-something-something-donald-t
I go to the second dash from the right and get the name that way. Then I get the city/state which is in the second dash from the left. In this manner, I've successfully found the duplicates in this database-but I'm having trouble thinking of a way to isolate the duplicate and delete it. In addition, I only want to delete the copy that does not have %near% in post_url. my question is, using the query here, how would I change this to delete the duplicate?
You're not going to be able to do it in one query. That's because you need to write a query that looks something like this:
DELETE FROM table
WHERE id IN (SELECT ... FROM table WHERE ...)
MySQL specifically prohibits this. You can't delete based on a subquery that references the same table. You also can't rewrite this query using JOINs.
There is an easy solution, though: use a temporary table and two queries.
-- build the list of IDs to delete
CREATE TEMPORARY TABLE temp
SELECT ... FROM table WHERE ...
-- now delete those items
DELETE FROM table
WHERE id IN (SELECT id FROM temp);
You can improve performance with JOINs and indexes.
The key to "isolating" the duplicates is to ensure that every item you want to delete has a primary key - that way you can easily build a list of IDs to delete. If your table don't have primary keys, you are reduced to doing WHERE clauses and JOINs on multiple columns - that gets messy very quickly.
Does MySQL have an UPDATE syntax that would allow me to update a whole row (not individual columns)?, something like this:
UPDATE `table1`
LEFT JOIN `table2` USING (`myColumn`)
SET `table1`.* = `table2`.*
Both table1 and table2 have the exact same structure.
The column names are variable, and subject to change.
Unfortunately I can't use a REPLACE query because the tables were badly designed and I'm not at liberty to modify them. The joining column doesn't have a unique index assigned to it, it only has a normal index.
"The column names are variable, and subject to change" - This is so wrong, if you rely on column order not col names, one day it will hit you in the head. Update will work with explicit col names: sqlfiddle.
I want to update some results in a table that would match a few conditions (i.e. variables from other tables to match a SELECT statement)
I've found something similar to this, on the net:
START TRANSACTION;
SELECT * FROM score_test,score_2,score_3, etc WHERE score=20000 AND score_test.id=score_2.id AND etc.. FOR UPDATE;
UPDATE score_test SET name='Test';
COMMIT;
NOTE: UPDATE score_test SET ... WHERE does not satisfy my needs as I need to gather the results that satisfy the SELECT statement
But it didn't work. It updates all my fields. What I am looking for is a syntax to use to UPDATE only the RESULTS from the SELECT statement.
My database is split into 10-15 tables and conditions may vary as I have to update some fields that STRICTLY accomplish some conditions that depend on the queries from other tables.
SQL UPDATE statements accept WHERE clauses just like SELECT statements do:
UPDATE score_test SET name='Test' WHERE score=20000;
edit
You can also treat the part following UPDATE as roughly the same as the part of a SELECT which follows FROM, which means you can do joins:
UPDATE score_test
JOIN test ON test.id=score_test.test_id
SET score_test.name = 'Test'
WHERE score_test.score=20000
The hints for this are in the UPDATE documentation, where it uses the table_reference symbol in the syntax definition. The syntax for table_reference is defined on the JOIN page. Implying identical treatment in both SELECT and UPDATE queries.
note on FOR UPDATE
the FOR UPDATE clause in a SELECT statement does not actually do anything related to updates... it only gathers a lock on the rows. You still need to follow that with an appropriate UPDATE query which does all the necessary JOINS and WHEREs (likely the same as your SELECT)
There are multiple ways to accomplish what you are asking. The simplest to just satisfy your question is to just do an update.
UPDATE score_test SET name='Test' WHERE score=20000;
If you want to satisfy conditions from multiple tables, you can use joins, just like a select statement, in the update statement.
You can further accomplish your goals, if you have such a complex use case, by creating a temporary table that holds the IDs of the items you want to edit, and cull that table one by one through multiple DELETE queries until you have the set you want to update.
Basically I am creating a summary table.
The issue is that sometimes the data in the primary table is modified manually. I am using an ON DUPLICATE KEY UPDATE, however I also need something like ON MISSING KEY DELETE. The summary needs to update to the changed data.
Is the best solution really to simply delete all summary records and re-run the INSERT SELECT query? It just doesn't seem like a good idea.
Any keys not in the select query, should not be in the summary table.
After you've populated the summary_table, you could do this:
DELETE s FROM summary_table s LEFT OUTER JOIN original_table o ON s.id = o.id
WHERE o.id IS NULL;
That will remove from summary_table any rows where the id no longer exists in the original_table.
I don't think there's any way you can do this in one statement.
i'm not sure i understand, but it sounds like you want triggers on the primary table for INSERT and UPDATE that add to the summary, and another trigger on DELETE that subtracts from the summary...
If the summary query is fast and changes are sporadic, you can just rerun the summary. You might consider using triggers so you remove 1 when deleting, add 1 when inserting etc
Is there a way to remove all repeat rows from a MySQL database?
A couple of years ago, someone requested a way to delete duplicates. Subselects make it possible with a query like this in MySQL 4.1:
DELETE FROM some_table WHERE primaryKey NOT IN
(SELECT MIN(primaryKey) FROM some_table GROUP BY some_column)
Of course, you can use MAX(primaryKey) as well if you want to keep the newest record with the duplicate value instead of the oldest record with the duplicate value.
To understand how this works, look at the output of this query:
SELECT some_column, MIN(primaryKey) FROM some_table GROUP BY some_column
As you can see, this query returns the primary key for the first record containing each value of some_column. Logically, then, any key value NOT found in this result set must be a duplicate, and therefore it should be deleted.
These questions / answers might interest you :
How to delete duplicate records in mysql database?
How to delete Duplicates in MySQL table.
And idea that's often used when you are working with a big table is to :
Create a new table
Insert into that table the unique records (i.e. only one version of the duplicates in the original table, generally using a select distinct)
and use that new table in your application ; or drop the old table and rename the new one to the old name.
Good thing with this principle is you have the possibility to verify what's in the new table before dropping the old one -- always nice to check that sort of thing ^^