SQL Delete with SELECT - mysql

I've got the following select query:
SELECT opt.product_option_id
FROM `oc_product_option_value` AS opt_val, `oc_product_option` AS opt
WHERE `opt`.`product_option_id` = `opt_val`.`product_option_id`
AND `opt_val`.`price` = '0.0000'
I thought that i could use that in an delete query:
DELETE oc_product_option, oc_product_option_value FROM oc_product_option
INNER JOIN oc_product_option_value
WHERE `oc_product_option`.`product_option_id` = `oc_product_option_value`.`product_option_id`
AND `oc_product_option_value`.`price` = '0.0000'
But that deleted ALL rows in oc_product_option. So what did i do wrong?

Can you give this a try?
DELETE t1 FROM oc_product_option t1
JOIN oc_product_option_value t2
WHERE `t1`.`product_option_id` = `t2`.`product_option_id`
AND `t2`.`price` = '0.0000'
Is it the intetion to delete the rows of both tables?

You make a circular dependence and this is why you get this result
Bellow query should delete only rows that have id in oc_product_option and price zero.
Or you have to define range of ids in oc_product_option using another criteria to filter oc_product_option table
DELETE FROM oc_product_option o
WHERE o.product_option_id in (SELECT opt.product_option_id FROM oc_product_option_value
where `oc_product_option_value`.`price` = '0.0000')

Related

How to make SQL-request for UPDATE columns with condition properly?

Iam so weak in SQL, please help. I have 2 tables with same columns: quantity and SKU. Need UPDATE Table_2 quantity with values from Table_1 quantity for strings with same SKU.
Seems it must looks like this:
UPDATE Table_2
SET Table_2.quantity = Table_1.quantity
WHERE Table_2.SKU = Table_1.SKU
;
How make that request properly?
You could use a inner join update
UPDATE Table_2
INNER JOIN able_1 ON Table_2.SKU = Table_1.SKU
SET Table_2.quantity = Table_1.quantity
You need to use aliases and join like:
Update t2
set t2.quantity = t1.quantity
from Table_2 as t2
inner join Table_1 as t1 on t1.SKU = t2.SKU

Invalid use of group function 1111

I keep getting an invalid use of group function. I'm looking to sum the values of one table and return the answer to the original table. I will be using this in a trigger.
But I keep getting an invalid use of group function 1111
UPDATE `Order`
INNER JOIN orderitem
ON order.OrderID = orderitem.OrderId
SET Order.TotalAmmount = SUM(orderitem.UnitPrice)
WHERE orderitem.OrderitemId = order.OrderId
Use a sub-query to aggregate:
UPDATE `Order`
SET `Order`.TotalAmmount =
(SELECT SUM(UnitPrice)
FROM orderitem
WHERE OrderitemId = `Order`.OrderId)
You can't use an aggregated result directly in a set value (because the level of aggregation between the result and each row of the table is not the same)
you should use an inner join on subquery for aggregated result and use the result for the subquery
UPDATE `Order`
INNER JOIN (
select orderitemID, SUM(orderitem.UnitPrice) sum_price
from orderitem
group by orderitemID
) t on t.orderitemID = order.OrderId
SET Order.TotalAmmount = t.sum_price

MySQL: delete rows with "WHERE ... NOT IN" from only one single table

In a MySQL database I have a many-to-many relationship between two tables. For the sake of simplicity let's assume those tables map homes and their residents. I have a third table to map those relations (home_resident_relations). The latter table has an additional column datemodified that stores the date of the latest update of each row via triggers.
Now I want to get rid of all former residents for each home and only keep the current ones - that is those with the newest date.
I have already a working SELECT clause that will list me all old relations I want to delete:
SELECT * FROM `home_resident_relations` WHERE `resident_id` NOT IN
(SELECT tbl.`resident_id`
FROM `home_resident_relations` tbl
WHERE tbl.`datemodified` =
(SELECT max(tbl2.`datemodified`)
FROM `home_resident_relations` tbl2
WHERE tbl2.`home` = tbl.`home`
GROUP BY tbl2.`home`)
OR tbl.`datemodified` IS NULL
);
Now it would be a straight-forward idea to simply replace the SELECT * with a DELETE command to remove all those rows. However, this does not work due to error
#1093 - You can't specify target table 'home_resident_relations' for update in FROM clause
So here's my question:
How do I delete from a table while using it in the WHERE ... NOT IN clause?
Use a left join instead:
DELETE hrr
FROM `home_resident_relations` hrr LEFT JOIN
(SELECT tbl.`resident_id`
FROM `home_resident_relations` tbl
WHERE tbl.`datemodified` = (SELECT max(tbl2.`datemodified`)
FROM `home_resident_relations` tbl2
WHERE tbl2.`home` = tbl.`home`
GROUP BY tbl2.`home`
) OR
tbl.`datemodified` IS NULL
) tt
ON hrd.resident_id = tt.resident_id
WHERE tt.resident_id IS NULL;
This works for both the SELECT and DELETE.
Try using DELETE with join:
DELETE FROM `home_resident_relations`
LEFT OUTER JOIN
(SELECT tbl.`resident_id`
FROM `home_resident_relations` tbl
WHERE tbl.`datemodified` =
(SELECT max(tbl2.`datemodified`)
FROM `home_resident_relations` tbl2
WHERE tbl2.`home` = tbl.`home` )
OR tbl.`datemodified` IS NULL) s
ON(s.`resident_id` = `home_resident_relations`.`resident_id`)
WHERE s.`resident_id` is null

How to filter rows `(a,b)` and `(b,a)` to a single row `(a,b)` in SQL-result?

How to filter rows (a,b) and (b,a) to a single row (a,b) in SQL-result?
In SQL I join a table with itself and extract all rows for which the primary key match and some other attribute don't match.
The result is that every row is "duplicated" in result. How do I filter these as described above ?
SELECT t1.courseId, t1.teacherId, t2.teacherId
FROM Gives AS t1 INNER JOIN Gives AS t2 ON t1.courseId = t2.courseId AND t1.teacherName <> t2.teacherName
Gives result:
dIntProg mch jat
dIntProg jat mch
dDbb ira sch
dDbb sch ira
Try this?
SELECT t1.courseId, t1.teacherId, t2.teacherId
FROM Gives AS t1 INNER JOIN Gives AS t2
ON t1.courseId = t2.courseId
AND t1.teacherName < t2.teacherName
Usually you would have to use GROUP BY to eliminate duplicates and use aggregate functions on all fields that are not part of the GROUP BY criteria.
For instance:
SELECT name, SUM(myCount)
FROM myTable
GROUP BY name

How to subselect based on multiple column key

I'm working with a legacy database that uses a three column key for products. I want to select all products that have a status of 'A' or that have a matching record in a second table. If it were a single column primary key (like 'id'), I would do it this way:
SELECT * FROM `product`
WHERE `status` = 'A'
OR `id` IN (SELECT `foreign_key` FROM `table2`)
I can't figure out how to do the IN-clause subselect with three keys though. I suppose I can concatenate the keys together and compare the strings, but that seems horribly inefficient. Is there a way to do this without concatenation?
You can LEFT JOIN table product and table2 on the composite key, then status = 'A' OR table2.id IS NOT NULL
A LEFT [OUTER] JOIN can be faster than an equivalent subquery because the server might be able to optimize it better
SELECT * FROM product p1
WHERE status = 'A'
OR EXISTS (SELECT *
FROM table2 t2
WHERE t2.id = p1.foreign_key
AND t2.other_key = p1.secret_key
...
);
Do a left join :)
SELECT p.* FROM product p
LEFT JOIN table2 t2 on p.key1 = t2.key1 and p.key2 = t2.key2 and p.key3 = t2.key3
WHERE status = 'A' OR t2.key1 IS NOT NULL
You could use a UNION:
SELECT *
FROM 'product'
WHERE 'status' = 'A'
UNION
SELECT *
FROM 'product'
JOIN 'table2'
ON (product.id = table2.foreign_key
AND ...)