我有一个产品,类别和“productsInCategories”的数据库,如下所示:
用户
id█ name ▌
▀▀█▀▀▀▀▀▀▀▀▌
1 █ john ▌
69█ jane ▌
产品
id█ name █ cost █description▌
▀▀█▀▀▀▀▀▀▀▀█▀▀▀▀▀▀█▀▀▀▀▀▀▀▀▀▀▀▌
21█snickers█ 23 █ foo ▌
34█ mars █ 20 █ bar ▌
37█ daim █ 21 █ oofrab ▌
79█ banana █ 8 █ foobar ▌
80█ apple █ 10 █ barfoo ▌
分类
id█ userId █ name ▌
▀▀█▀▀▀▀▀▀▀▀▀█▀▀▀▀▀▀▀▀▀▌
10█ 69 █chocolate▌
55█ 69 █favorites▌
20█ 1 █ fruit ▌
ProductsInCategories
categoryId█productId▌
▀▀▀▀▀▀▀▀▀▀█▀▀▀▀▀▀▀▀▀▌
10 █ 21 ▌
10 █ 34 ▌
20 █ 79 ▌
20 █ 80 ▌
55 █ 21 ▌
55 █ 37 ▌
这会产生一些可以看作的东西:
Users
john
fruit
banana
apple
jane
chocolate
snickers
mars
daim
favorites
snickers
daim
当我想获得某个类别的所有产品时,我会做类似的事情:
SELECT *
FROM Products
INNER JOIN ProductsInCategories
ON Products.Id=ProductsInCategories.product
WHERE category=@0
,@0=categoryId
这一切都正常,插入或删除产品非常简单。 但是我现在有一个问题,我无法解决这个问题。
即删除类别。我将如何继续这样做?我已经工作了几个小时,但似乎无法让它工作。 如果用户删除某个类别,我希望该类别中仅存在 的所有产品与相关的productInCategories记录一起删除。 如果说用户“Jane”删除了她的“巧克力”类别,那么我想删除产品“火星”而不是“窃笑”或“火星”,因为它们也存在于“收藏夹”类别中
答案 0 :(得分:4)
除非您在架构中设置了级联删除,否则您需要使用3个删除语句,每个表一个。
-- Delete category 10 from Categories table.
DELETE FROM Categories WHERE Id=10;
-- Delete category 10 from ProductsInCategories table.
DELETE FROM ProductsInCategories WHERE CategoryId=10;
-- Delete all products that are no longer in a category
DELETE Products
FROM Products
LEFT JOIN ProductsInCategories
ON ProductId=Products.Id
WHERE ProductId IS NULL;
答案 1 :(得分:1)
一些让您前进的pseodocode:
Delete from ProductsIncategories where category = X
Delete from products where productID in (
select productID from
products left outer join productsincategories
on products.productID = productsincategories.productID
where
productsincategories.categoryid is null
)
delete from categories where category = x
如果您首先删除类别中的产品,则取决于其他表格,并且不依赖于它。
现在在任何类别中查找产品 - 这些只是要删除的类别 - 这是通过从产品到产品类别的左外部连接来完成的 - 这给出了产品的所有行,如果它们是null没有类别产品的匹配记录
删除类别本身,因为现在没有任何内容链接到它。
作为旁注,请考虑不要仅删除此类别中的产品,而是提供这些产品的报告供人们审核和清理。在我看来,工作可能会经常丢失。也许至少在你删除之前给他们确认的机会
另请注意,中间声明将删除不在某个类别中的每个产品..在这样的问题上有两种思想流派
如果您只想删除仅属于此类别的产品且毯子删除效果不佳,那么这样的内容可能有所帮助:
select productID form
from
products as p
inner join productsincategories as pic
on PIC.productid = p.productid
inner join (
select distinct productID from productsincategories
where categoryid = X
) as t
on t.productid = p.productid
group by
productid
having
count(*) = 1
这是使用Joachim Isaksson的小提琴选择实际行动(现在约翰希姆+ 1'你的回答)
http://sqlfiddle.com/#!3/5a744/22
LEFT OUTER JOINS - 快速笔记
table a
id
1
2
table b
aID value
1 x
1 y
a left outer join b (select * from a left outer join b on a.id = b.aID)
id aID value
1 1 x
1 1 y
2 NULLNULL
b left outer join a (select * from b left outer join a on a.id = b.aID)
aID value id
1 x 1
1 y 1
左外连接为您提供左侧表格中的所有内容以及右侧表格中的匹配项。如果左表中有一行而右表没有,则右表中的所有列都会得到NULL。希望有帮助,但值得谷歌搜索和实验,以适应。
当您想要查看所有商品的销售情况时,它非常有用,但您希望获得商品列表是否有销售。或者就像我们在这里使用它来查找一个表中没有在另一个表中的所有内容,只选择“右”表为空的位置