mysql multiple table DELETE rows syntax error - mysql

How come this query:
SELECT *
FROM `store_catalog_product_option`
JOIN `store_catalog_product_option_type_value`
WHERE `product_id`=15676
AND `store_catalog_product_option_type_value`.`sku` LIKE '%UNIT_%'
retrieve data.
But replacing
select *
with
delete
as such
DELETE
FROM `store_catalog_product_option`
JOIN `store_catalog_product_option_type_value`
WHERE `product_id`=15676
AND `store_catalog_product_option_type_value`.`sku` LIKE '%UNIT_%'
give syntax error:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'JOIN store_catalog_product_option_type_value WHERE product_id=15676 AND `sto' at line 1

For multi-table deletes,
For the first multiple-table syntax, only matching rows from the tables listed before the FROM clause are deleted. the second multiple-table syntax, only matching rows from the tables listed in the FROM clause (before the USING clause) are deleted.
DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3
WHERE t1.id=t2.id AND t2.id=t3.id;
Or:
DELETE FROM t1, t2 USING t1 INNER JOIN t2 INNER JOIN t3
WHERE t1.id=t2.id AND t2.id=t3.id;
And for LEFT JOIN, you should use something like
DELETE t1 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;

Your JOIN should have an ON part

You can try somthing like this:-
DELETE FROM `store_catalog_product_option` A
JOIN `store_catalog_product_option_type_value' B
ON A.ID = B.ID
WHERE A.`product_id`=15676
AND B.`sku` LIKE '%UNIT_%'
Alternatively you can use:-
DELETE A
FROM `store_catalog_product_option` A
JOIN `store_catalog_product_option_type_value' B
ON A.ID = B.ID
WHERE A.`product_id`=15676
AND B.`sku` LIKE '%UNIT_%'
...to delete only from store_catalog_product_option

I needed indeed to use a multiple table syntax, including also a ON condition for the JOIN.
Since i wanted to delete rows in both tables , here is my working query, after your help:
DELETE O, V FROM `store_catalog_product_option` O JOIN `store_catalog_product_option_type_value` V on O.option_id=V.option_id WHERE `product_id`=15676 AND V.`sku` LIKE '%UNIT_%'

Related

MySQL Update & Join

I have a MySQL table containing contact details, and I need to flag duplicates of the column "PHONE1" into another flag column called "DUPLICATE" (ignoring the first, original, row).
I found an SQL tutorial with an example SQL query doing almost exactly what I want here: https://www.sqlservertutorial.net/sql-server-basics/sql-server-update-join/.
I modified the tutorial example, and I can "SELECT" the duplicate rows correctly with the following query:
SELECT t1.ID, t1.`Contact Name`, t1.PHONE1
FROM new_leads_test2 AS t1
INNER JOIN new_leads_test2 AS t2
ON (t1.PHONE1 = t2.PHONE1
AND t1.ID > t2.ID)
this "SELECT" query works 100%, but when I try to alter this query to actually UPDATE the rows (per the tutorial), I get an SQL syntax error. Here's my query that generates the error:
UPDATE t1
SET t1.duplicate = t2.ID
FROM new_leads_test2 AS t1
INNER JOIN new_leads_test2 AS t2
ON (t1.PHONE1 = t2.PHONE1
AND t1.ID > t2.ID)
This results in an SQL error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use
near 'FROM new_leads_test2 AS t1 INNER JOIN new_leads_test2 AS
t2 ON t1.PHONE1 = t2.' at line 3
Can anyone please help me with this?
We might put SET after INNER JOIN because UPDATE Statement, table_reference use before SET
BTW maybe you might not need FROM
UPDATE [LOW_PRIORITY] [IGNORE] table_reference
SET assignment_list
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
so we might use like below.
UPDATE new_leads_test2 AS t1
INNER JOIN new_leads_test2 AS t2
ON (t1.PHONE1 = t2.PHONE1
AND t1.ID > t2.ID)
SET t1.duplicate = t2.ID
Your example is a SQL Server syntax, not MySQL.
Try with:
UPDATE new_leads_test2 t1
INNER JOIN new_leads_test2 t2
ON (t1.PHONE1 = t2.PHONE1 AND t1.ID > t2.ID)
SET t1.duplicate = t2.ID

DELETE rows where userID is not found in separate table

If I run the following SQL statement:
SELECT * FROM `user-data` t1
LEFT JOIN `users` t2 ON t1.userID = t2.id
WHERE t2.id IS NULL
It gives me all the rows that don't have a matching row in the users table, (because the user has been deleted). But I cannot simply turn this into a DELETE statement:
DELETE FROM `user-data` t1
LEFT JOIN `users` t2 ON t1.userID = t2.id
WHERE t2.id IS NULL
As I get the following error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 't1
LEFT JOIN `users` t2 ON t1.userID = t2.id
WHERE t2.id IS NULL' at line 1
What can I do to delete all the rows in user-data that don't have an existing user in table users?
instead of using LEFT OUTER JOIN and IS NULL try a WHERE NOT EXISTS. Something like this:
DELETE t1
FROM user-data t1
WHERE NOT EXISTS
(
SELECT id FROM FROM users WHERE user-data.userID = users.id)
)
A delete join query is absolutely valid in MySQL. I think the issue is that you did not specify an alias after DELETE. Hence, the following should work:
DELETE t1 FROM `user-data` t1
LEFT JOIN `users` t2
ON t1.userID = t2.id
WHERE t2.id IS NULL
I suspect the need for an alias here arises because it is not clear from which table we want MySQL to do a deletion. Note that using the WHERE NOT EXISTS approach does not require an alias after DELETE.
I seem to remember that you cannot use table aliases in a DELETE. Also you can specify the table where you want to delete from like this:
DELETE `user-data`.* FROM `user-data`
LEFT JOIN `users` ON `user-data`.userID = `users`.id
WHERE `users`.id IS NULL

Issue with SQL join query

this is a simplified version of my query. It runs in SQLite without an issue, but not so in MYSQL.
Error: Unknown column 'tab2.key' in 'on clause'
SELECT
tab2.key AS remarksId,
tab1.sessionDate AS date,
tab1.sessionStart AS startTime
FROM
table1 AS tab1,
table2 AS tab2,
table3 AS tab3,
table4 AS tab4
INNER JOIN
table5 AS tab5
ON
tab5.remarkId = tab2.key
WHERE
tab1.userId='<anyNumber>' AND
tab2.objectiveId='<anyKey>' AND
tab1.reportId=tab2.reportId AND
tab1.reportId=tab3.key AND
tab4.key=tab3.sortieId
ORDER BY date, startTime;
To put the columns in ` unfortunately was no help.
I'm not sure if naming a column 'key' is a good practice (MYSQL Keywords), but I have to handle this somehow, due to existing installations. For a quick test, I renamed the 'key'-columns, but also without any success.
Thanks a lot
Simply put, Don't mix join notations, and if given the choice use the current ANSI 92 join syntax instead of the 89 standard (yes... that's 1992 and 1989!)
Secondly... aliases are to help you save typing and handle multiple references to the same table.... so... simplify the names t1, t2, t3...
Lastly... if you have to use reserved/restricted words in mySQL use backticks.
SELECT t2.`key` AS remarksId
FROM table1 t1
INNER JOIN table2 t2
ON t1.reportId = t2.reportId
INNER JOIN table3 t3
ON t1.reportId = t3.`key`
INNER JOIN table4 t4
ON t4.`key` = t3.sortieId
INNER JOIN table5 t5
ON t5.remarkId = t2.`key`
WHERE t1.userId = '<anyNumber>'
AND t2.objectiveId = '<anyKey>'
ORDER BY `date`, startTime;

Delete MySQL row using where clause

I'm trying to delete duplicate rows according to some fileds.
When I'm running the query below:
delete
from slowmo_vid as sv1, slowmo_vid as sv2
where sv1.video_id = '2luh6g3ni5ex'
and sv1.slowmo_end_t<=sv2.slowmo_end_t;
I'm getting the error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as sv1, slowmo_vid as sv2
where sv1.video_id = '2luh6g3ni5ex'
and sv1.slowmo_end' at line 2
The fields of the tables are : id, video_id internal_uri, slowmo_end_t
You seem to be trying to do an ANSI-92 style inner join inside a DELETE statement. But the WHERE clause cannot simultaneously be used to enforce the join and enforce a restriction on a result set. Instead, do the following explicit INNER JOIN to remove the records you want. Notice that it is clear what role the WHERE clause is playing.
Update: If you want to delete all records except for the one containing the max video_id then you can add a nested subquery to the WHERE clause.
DELETE sv1.*
FROM slowmo_vid sv1
INNER JOIN slowmo_vid sv2 ON sv1.slowmo_end_t <= sv2.slowmo_end_t
WHERE sv1.video_id = '2luh6g3ni5ex' AND
sv1.video_id <> (SELECT x.id
FROM (SELECT MAX(t.video_id) AS id
FROM slowmo_vid t) x)
You can specify multiple tables in a DELETE statement to delete rows
from one or more tables depending on the particular condition in the
WHERE clause. However, you cannot use ORDER BY or LIMIT in a
multiple-table DELETE. The table_references clause lists the tables
involved in the join. Its syntax is described in Section 12.2.8.1,
“JOIN Syntax”.
http://dev.mysql.com/doc/refman/5.6/en/delete.html
The example in the manual is:
DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3
WHERE t1.id=t2.id AND t2.id=t3.id;
You cannot use aliases on DELETE statement. You can try with:
DELETE FROM myAlias USING `my_table` AS myAlias
Or try without any aliases

Does the table in the FROM clause have to be in the WHERE clause?

I've done a similar JOIN in a UPDATE script, but I used the same table in the SET and WHERE clause. In this DELETE script I need to delete from one table where a condition is true in another table. For example:
DELETE FROM `db_A`.`table_A`
JOIN `db_B`.`table_B`
ON `table_A`.`id` = `table_B`.`id`
WHERE `table_B`.`name` = 'Remove Me'
Can I do something like this?
The MYSQL documentation makes it very clear that yes you can do this
You can specify multiple tables in a
DELETE statement to delete rows from
one or more tables depending on the
particular condition in the WHERE
clause. However, you cannot use ORDER
BY or LIMIT in a multiple-table
DELETE. The table_references clause
lists the tables involved in the join.
Its syntax is described in Section
12.2.8.1, “JOIN Syntax”.
For the first multiple-table syntax,
only matching rows from the tables
listed before the FROM clause are
deleted. For the second multiple-table
syntax, only matching rows from the
tables listed in the FROM clause
(before the USING clause) are deleted.
The effect is that you can delete rows
from many tables at the same time and
have additional tables that are used
only for searching:
DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3
WHERE t1.id=t2.id AND t2.id=t3.id;
Or:
DELETE FROM t1, t2 USING t1 INNER JOIN t2 INNER JOIN t3
WHERE t1.id=t2.id AND t2.id=t3.id;
These statements use all three tables
when searching for rows to delete, but
delete matching rows only from tables
t1 and t2.
The preceding examples use INNER JOIN,
but multiple-table DELETE statements
can use other types of join permitted
in SELECT statements, such as LEFT
JOIN. For example, to delete rows that
exist in t1 that have no match in t2,
use a LEFT JOIN:
DELETE t1 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;
The syntax permits .* after each tbl_name for compatibility with Access.
From Delete Manual, the table you want to delete goes between DELETE and FROM. Unless you want to delete from all tables involved in the join
DELETE `db_A`.`table_A` FROM `db_A`.`table_A`
JOIN `db_B`.`table_B`
ON `table_A`.`id` = `table_B`.`id`
WHERE `table_B`.`name` = 'Remove Me'
As a general answer, yes. You can join to the second table with the condition, as you have stated, or pull the ids in a subcommand, like:
DELETE FROM T1
WHERE id in (SELECT id FROM T1 JOIN T2 ON X = Y WHERE T2.Val = "X")
This is a bit heavy weight, but if T2 is the child, you can reduce this to:
(SELECT Y from T2 WHERE Val = "X")
Make sense?