2013-10-02 141 views
4
id_specific_price id_product 
------------------------------- 
      1    2 
      2    2 
      3    2 
      4    3 
      5    3 
      6    3 
      7    3 

需要删除重复项,预期结果:查询,删除与GROUP BY重复

id_specific_price id_product 
------------------------------- 
      3    2 
      7    3 

SELECT * 
    FROM ps_specific_price 
WHERE id_specific_price NOT IN 
(SELECT MAX(id_specific_price) 
    FROM ps_specific_price 
    GROUP BY id_product) 

的作品,但

DELETE FROM ps_specific_price 
WHERE id_specific_price NOT IN 
(SELECT MAX(id_specific_price) 
    FROM ps_specific_price 
    GROUP BY id_product) 

没有。有很多例子可以解决这个问题,但由于某种原因,我无法适应它。我相信这是GROUP BY。例如:

DELETE FROM ps_specific_price 
WHERE id_specific_price NOT IN 
(SELECT MAX(p.id_specific_price) 
    FROM (SELECT * FROM ps_specific_price) as p) 
    GROUP BY id_product 

我在哪里出错了?

+0

您不应使用您在子查询中删除的表。您应该使用带有游标的存储过程来存档此目标。 –

+0

存储过程是魔鬼的工作。如果它不能在SQL中解决(它可能可以,但可能是特定于供应商的),我建议在应用程序级别(从Java或PHP等)执行它 - select ...;从...删除id_specific_price(...) –

+0

@CedricSimon Quoi?你的建议是(也许)只对mysql有效,它不喜欢在同一语句中读取已删除或更新的表。 (除非阅读参考做了一些聚合,IIRC) – wildplasser

回答

9

如果你正在寻找对MySQL的解决方案,那么你可以沿着使用合适的multi table DELETE语法与JOIN这样

DELETE p 
    FROM ps_specific_price p JOIN 
(
    SELECT id_product, MAX(id_specific_price) id_specific_price 
    FROM ps_specific_price 
    GROUP BY id_product 
) d 
    ON p.id_product = d.id_product 
    AND p.id_specific_price <> d.id_specific_price; 

结果:

 
| ID_SPECIFIC_PRICE | ID_PRODUCT | 
|-------------------|------------| 
|     3 |   2 | 
|     7 |   3 | 

这里是SQLFiddle演示

+0

太棒了!这个人就像一个魅力!我非常感谢你! – popkutt

+0

很高兴知道。你非常欢迎:)如果这是你正在寻找的请,请考虑** [接受](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work )** 答案。 – peterm

1

试试这个:

CREATE TABLE ps_specific_price (
    id_specific_price NUMBER, 
    id_product NUMBER 
); 

INSERT INTO ps_specific_price (id_specific_price, id_product) VALUES (1, 2); 
INSERT INTO ps_specific_price (id_specific_price, id_product) VALUES (2, 2); 
INSERT INTO ps_specific_price (id_specific_price, id_product) VALUES (3, 2); 
INSERT INTO ps_specific_price (id_specific_price, id_product) VALUES (4, 3); 
INSERT INTO ps_specific_price (id_specific_price, id_product) VALUES (5, 3); 
INSERT INTO ps_specific_price (id_specific_price, id_product) VALUES (6, 3); 
INSERT INTO ps_specific_price (id_specific_price, id_product) VALUES (7, 3); 

COMMIT; 

DELETE FROM ps_specific_price ps 
    WHERE ps.id_specific_price NOT IN (
    SELECT MAX(id_specific_price) 
     FROM ps_specific_price ps_in 
    WHERE ps_in.id_product = ps.id_product 
    ); 

SELECT * FROM ps_specific_price; 

ID_SPECIFIC_PRICE  ID_PRODUCT    
---------------------- ---------------------- 
3      2      
7      3      

必须从内部查询与该表从外一个连接表。

我正在使用Oracle 11g R2。我对SQLFiddle进行了检查,并且我的DELETE语句对MySQL无效 - 没有安装那个,也没有太多经验,但是你没有说明你正在使用哪个数据库。

+0

谢谢。我忘记提及有成千上万的行,这些只是第一个7.所以我需要首先找到重复项,然后删除它们 – popkutt

+0

是的,但是您使用子查询“寻找”它们,无论有多少。请告诉我们您使用的是哪个数据库。另外,你应该检查这个链接:http://stackoverflow.com/questions/18932/how-can-i-remove-duplicate-rows?rq=1 –

0

可能是你想尝试:

DELETE FROM ps_specific_price WHERE(id_product,id_specific_price)NOT IN(SELECT id_product,MAX(id_specific_price)FROM ps_specific_price GROUP BY id_product);

我在我的Teradata数据库上试过这个,它工作。

在您先前的查询中,我看到您错过的唯一一件事是映射id_product,它的最大价格为 并带有删除集。在删除之前,删除将不知道它必须匹配pid和价格。

希望这会有所帮助。

+0

谢谢。它不适用于我的MySQL数据库。什么是Teradata数据库?其数据库为 – popkutt

+0

。如果它在我的Sql上,则可以使用外部删除表中的id_product在子查询中加入id_product。 –

+0

@popkutt:你没有提到mysql(在引用被更新或删除的表时,**非常受限制) – wildplasser