2011-02-18 114 views
0

我的问题是我想从两个表中删除记录,删除是以下查询的结果的记录:删除记录/哪里存在问题

SELECT AVG(pr.rating) AS rating_average 
FROM products p 
INNER JOIN product_ratings pr 
ON pr.product_id = p.product_id 
GROUP BY p.product_id 
HAVING AVG(pr.rating) < 3 

以上查询显示的平均收视率小于3的产品,我想从上述查询中删除所有结果的产品及其关联评级。

我看着DELETE FROM product_ratings, products WHERE EXISTS (//above query),但这并没有工作,我一直在尝试各种DELETE语句无济于事。

我已阅读以下内容,但仍无法找到解决方案:SQL: DELETE Statement & SQL: EXISTS Condition

表是productsproduct_ratings,具有以下结构:

products 
-------- 
product_id [PK] | link | ... 

product_ratings 
--------------- 
rating_id [PK] | rating | product_id 

得到任何帮助,以及参考资料的链接,以更好地了解它是如何做。

编辑:不说明我使用,这是MySQL的

什么RDBMS道歉

EDIT2:现在有点糊涂了,@马丁的例子不使用临时表像其他的答案,我想这是因为我的模糊问题没有用我使用的RDBMS进行陈述?

+0

您使用的是什么RDBMS? – 2011-02-18 20:33:12

回答

2

您现在已经添加了MySQL标记。在这种情况下,这可能会为你做这项工作。

DELETE products, 
     product_ratings 
FROM products, 
     product_ratings 
WHERE product_ratings.product_id = products.product_id 
     AND product_ratings.product_id IN 
(SELECT product_id 
     FROM (SELECT p.product_id 
       FROM products p 
         LEFT JOIN product_ratings pr 
         ON pr.product_id = p.product_id 
       GROUP BY p.product_id 
       HAVING COALESCE(AVG(pr.rating), 0) < 3) T) 

MySQL does support一个多表DELETE语法。派生表是为了避免在子查询(it materializes the result into a temporary table)中不允许变更(更新或删除目标)表引用的问题。

+0

对不起,马丁,我去了AFK,这是我需要的,但是,有没有办法扩展'HAVING AVG(rating)<3`,这样它会删除是否存在评级?伪代码将是:`有AVG(评级)<3或不存在` – Daniel 2011-02-18 21:00:13

1

p.product_id添加到您的select语句中,并将该查询的结果存储在临时表中。然后使用该临时表从两个单独的删除操作中删除product_ratingsproducts

删除的具体语法将取决于您正在使用的RDBMS。

0

如果你的DBMS支持的话,你可以用一个ON DELETE CASCADE子句添加一个外键约束的product_ratings表,例如:

ALTER TABLE product_ratings ADD CONSTRAINT fk_prodratings_prods 
    FOREIGN KEY (product_id) REFERENCES products(product_id) 
    ON DELETE CASCADE; 

一旦你加入这个限制,您只需要products表中的DELETE。然后,上述约束条件的ON DELETE CASCADE约束将删除您的评分,例如,

DELETE FROM products p 
WHERE (SELECT AVG(pr.rating) 
      FROM product_ratings pr 
     WHERE pr.product_id = p.product_id) < 3;