how do I fix this MySQL DELETE query? - mysql

I have three tables, products, shops, and sex. I wish to DELETE rows in the products table having a product_id such that there exists no equivalent product_id in the sex table.
Further, these rows in the products table must have a shop_id equal to the shop_id in the shops table for the row whose shops.shop value is 'www.shop.com'.
so far I have
DELETE FROM products USING shops WHERE
products.shop_id=shops.shop_id AND
shops.shop='www.shop.com' AND NOT EXISTS
(SELECT sex.product_id FROM sex WHERE
sex.product_id=products.product_id)
but it appears it is not acceptable to make reference to products in the subquery as I have done. (I get the error Unknown table 'products' in MULTI DELETE.) How do I fix my mistake?

You can use JOINs in your DELETE statement:
DELETE a
FROM products a
JOIN shops b ON a.shop_id = b.shop_id AND b.shop = 'www.shop.com'
LEFT JOIN sex c ON a.product_id = c.product_id
WHERE c.product_id IS NULL
This will DELETE only the products which have a corresponding row in the shops table with shop = www.shop.com, but only if that product also does not have a corresponding row in the sex table.

Related

How to get Data from three tables in one query where table 2 contains foreign keys from table 1 and 3

I want to get all the suppliers for one product with product details for which I am using following tables.
I have one Table products with columns
id(pk)
name
type
second table product_supplier with columns
psid(pk)
pid(fk from products)
sid(fk from supplier)
third table supplier with columns
id(pk)
firstname
lastname
I want to get data from these three tables in one mysql query.
Is this what you are looking for?
select p.*, s.*
from products p
inner join product_supplier ps on ps.pid = p.id
inner join supplier s on s.id = ps.sid
order by p.id, s.id
This will return each product along with all the associated suppliers.

Pull data from 3 tables

I have 3 tables as follows :
Table 1: Product
id_product [Primary Key],added_time.
Table 2: Category
id_category [Primary Key],Category_name.
Table 3: product_category
id_category,id_product [Both Foreign Keys]
I want to pull Data as
Category_name,No Of Products in this Category,Last time when product was added to Category(Latest product added_time).
You could use this SQL:
SELECT Category.Category_name,
Count(DISTINCT Product.id_product) AS num_products,
Max(Product.added_time) last_added_time
FROM Category
LEFT JOIN product_category
ON product_category.id_category = Category.id_category
LEFT JOIN Product
ON Product.id_product = product_category.id_product
GROUP BY Category.Category_name;
Note that by using LEFT JOIN you will be certain to list all categories even those for which no products exist. If you don't want those, replace both LEFT keywords with INNER.
Note also that in standard SQL you need to GROUP BY any columns you mention in the SELECT list, unless they are aggregated, like with MAX or COUNT.
SELECT C.`Category_name`,
(SUM(IF(P.`id_product`IS NULL,0,1))) AS No_of_Products,
MAX(P.`added_time`) AS Latest_time
FROM
Category C
LEFT JOIN
product_category P_C ON C.`id_category` = P_C.`id_category`
LEFT JOIN
Product P ON P.`id_product` = P_C.`id_product`
GROUP BY C.`id_category`
Hope this helps.

SQL - Updating table with informaton from another table

I am trying to run an update on my companies eshop, but I'm racking my brain trying to work out the correct SQL command to do the following:
I have three tables:
Products
------------
pId
pSearchParams
ProductCategories
------------------
pcProductId // products.pId
pcCategoryId // categories.catId
Categories
----------
catId
catName
I need to update the pSearchParams field in the products table with the information from the catName field in the categories table.
The only way I can do this is to link the products table to the productcategories table, as the productcategories table is the only way I can establish a link between the products table and the categories table.
The problem is that in the productcategories table, pcProductId is likely to contain the same information on multiple rows, the same goes for pcCategoryId (e.g. products can be in multiple categories)
I need to run an UPDATE statement to update all the pSearchParams fields in the products table with the relevant category names, allowing for multiple category names.
If I need to provide more information please let me know. Thanks.
UPDATE products AS p
JOIN productcategories AS pc ON (p.pId = pc.pcProductId)
JOIN categories AS c ON (pc.pcCategoryId = c.catId)
SET p.pSearchParams = c.catName
Update
UPDATE products AS p
SET p.pSearchParams = (
SELECT GROUP_CONCAT(c.catName SEPARATOR ' ')
FROM productcategories AS pc
JOIN categories AS c ON (pc.pcCategoryId = c.catId)
WHERE pc.pcProductId = p.pId
GROUP BY pc.pcProductId
)

MySQL Queries - Selecting from 2 tables and if exists in the other check field

I am trying to pull products from a table called products, I also have a table called product_ranges.
products
--------
id
name
model
product_ranges
--------------
id
product_id
other_id
SELECT p.id
FROM products As p
LEFT JOIN product_ranges As pr ON (pr.product_id = p.id AND pr.other_id = 16)
This will select all products and include the product_ranges table columns too if the product exists in it but if it does exist in this table and the other_id does not equal 16 I don't want the product to be in the returned results but if the product doesn't exist at all in the other table I want it in the results still.
I am sure I have done this years ago but can't think of the SQL for it - if anyone knows the right query I would be grateful, thanks.
Updated:
SELECT p.id
FROM products
LEFT JOIN product_ranges pr ON pr.product_id = p.id
WHERE (pr.product_id IS NULL OR pr.other_id = 16)

Inverse of Inner join (Intersect) with multiple foreign keys

Hi I want to get opposite of intersect from two tables.
I have a sale table and purchase table. What I want to do is get all purchases ids where not included in the sales table.
sale table
sale_id (pk)
product_id (fk)
purchase_id (fk)
purchase table
product_id (fk)
purchase_id (pk)
SELECT DISTINCT purchase_id
, product_id
FROM
purchase
INNER JOIN sale
USING (purchase_id, product_id);
Here is an example:
If I run the above code, this will be the result.
purchase_id product id
1 1
1 2
1 4
2 1
2 3
Now I want to get:
purchase_id product id
1 3
2 2
In short I want to get inverse of above code. Thanks in advance.
Okay, I think I understand better now.
This should return any entry in purchase that have no matching entry in sales.
SELECT
`purchase`.`purchase_id`, `purchase`.`product_id`
FROM `purchase`
LEFT JOIN `sale` ON `sale`.`purchase_id` = `purchase`.`purchase_id` AND `sale`.`product_id` = `purchase`.`product_id`
WHERE
`sale`.`sale_id` IS NULL
ORDER BY
`purchase`.`purchase_id`, `purchase`.`product_id`
If you want to get all the purchases that have no related values in the sales table, you can use a LEFT JOIN:
select
p.purchase_id
from
purchase as p
left join sale as s on p.purchase_id = s.purchase_id
where
s.purchase_id is null;
"Unilateral" joins (LEFT JOIN, RIGHT JOIN) are useful when you want to get data from a table even if data in another related table does not exist. Of course, that means that you can filter data from one table when there's no related data in a second table.
Hope this helps.
Looking at your updated question and your comment, I think that you want all the possible combinations not used.
You'll need to split this in two steps:
First you need all the possible combinations of purchase_id and sale_id values (the "cartesian product" of both the sets).
Then you need to get all the combinations already used.
Finally you need to exclude all the combinations already used.
This can be done using subqueries.
Step 1.
select distinct p.purchase_id, s.product_id from purchase as p, sale as s;
Step 2. (Your query)
select distinct
purchase_id, product_id
from
purchase as p
inner join sale as s
on (p.purchase_id = s.purchase_id and p.product_id = s.product_id);
Step 3. Put it all together
select
a.*
from
(select distinct p.purchase_id, s.product_id from purchase as p, sale as s) as a
left join (
select distinct
purchase_id, product_id
from
purchase as p
inner join sale as s
on (p.purchase_id = s.purchase_id and p.product_id = s.product_id)
) as e on (a.purchase_id = e.purchase_id and a.product_id = e.product_id)
where
e.purchase_id is null and e.product_id is null;