如何删除每个组的较小记录?

时间:2011-07-25 09:59:31

标签: sql select group-by max sql-delete

我的表价格具有当前架构:

item date         shift     price1  price2
1    20110723     day       40      50
1    20110723     night     42      52
1    20110723     weekend   42      52
2    20110723     Night     40      50
...

我希望保留表中每个项目的最高价格1或价格2的记录,即从表格中删除价格较小的1或价格2的记录。 如何编写sql?

我使用sybase ASE 12.5

2 个答案:

答案 0 :(得分:1)

在SQL Server(可能还有其他一些RDBMS)中,您可以使用CTEranking,如下所示:

WITH ranked AS (
  SELECT
    *,
    price1rank = RANK() OVER (PARTITION BY item ORDER BY price1 DESC),
    price2rank = RANK() OVER (PARTITION BY item ORDER BY price2 DESC)
  FROM Test1
)
DELETE FROM ranked
WHERE price1rank <> 1
  AND price2rank <> 1;

<强>更新

发布整个测试脚本,包括上面的DELETE语句,以便任何人都愿意使用它或只是验证它是否有效:

CREATE TABLE Test1 (
  item int,
  date date,
  shift varchar(30),
  price1 money,
  price2 money
);
GO
INSERT INTO Test1 (item, date, shift, price1, price2)
SELECT 1, '20110723', 'day    ', 40, 50 UNION ALL
SELECT 1, '20110723', 'night  ', 42, 52 UNION ALL
SELECT 1, '20110723', 'weekend', 42, 52 UNION ALL
SELECT 2, '20110723', 'Night  ', 40, 50;
GO
SELECT * FROM Test1
GO
WITH Test1Ranked AS (
  SELECT
    *,
    price1rank = RANK() OVER (PARTITION BY item ORDER BY price1 DESC),
    price2rank = RANK() OVER (PARTITION BY item ORDER BY price2 DESC)
  FROM Test1
)
DELETE FROM Test1Ranked
WHERE price1rank <> 1
  AND price2rank <> 1;
GO
SELECT * FROM Test1
GO
DROP TABLE Test1
GO

答案 1 :(得分:0)

如果您在oracle中工作,可以编写以下查询 -

delete from item_table where rowid not in
(
     select rowid from item_table 
     where (item,price1) in (select item,max(price1) from item_table group by item)
        or (item,price2) in (select item,max(price2) from item_table group by item)
)

我听说在sql server或mysql中没有rowid ... 请告诉我们您正在使用的数据库名称。

你也可以写如下..

delete from item_table where (item,date,shift,price1,price2 ) not in
    (
        select item,date,shift,price1,price2  from item_table 
        where (item,price1) in (select item,max(price1) from item_table group by item)
           or (item,price2) in (select item,max(price2) from item_table group by item)
    )