丢弃该组中不是MAX的行

时间:2014-07-08 13:51:04

标签: sql database postgresql

我有这样的数据:

   a       b        c
-------|--------|--------
  100  |   3    |   50
  100  |   4    |   60
  101  |   3    |   70
  102  |   3    |   70
  102  |   4    |   80
  102  |   5    |   90

a:关键 b:sub_id c:值

我想为每个具有非最大c列的元素添加a行。

我的结果表必须如下:

   a       b        c
-------|--------|--------
  100  |   3    |  NULL
  100  |   4    |   60
  101  |   3    |   70
  102  |   3    |  NULL
  102  |   4    |  NULL
  102  |   5    |   90

如何使用SQL查询执行此操作?

#UPDATE

我的关系表有大约十亿行。请提醒一下,同时提供答案。我不能等几个小时或一天才能执行。

4 个答案:

答案 0 :(得分:1)

在将要求更改为“更新表格”后更新:

with max_values as (
  select a,
         b,
         max(c) over (partition by a) as max_c
  from the_table
)
update the_table   
    set c = null
from max_values mv
   where mv.a = the_table.a
     and mv.b = the_table.b
     and mv.max_c <> the_table.c;

SQLFiddle:http://sqlfiddle.com/#!15/1e739/1

另一种可能的解决方案,可能更快(但您需要检查执行计划)

update the_table t1
  set c = null
where exists (select 1 
              from the_table t2
              where t2.a = t1.a
                and t2.b = t2.b 
                and t1.c < t2.c);

SQLFiddle:http://sqlfiddle.com/#!15/1e739/2

但是有了“十亿”行,就没有办法真的很快。

答案 1 :(得分:1)

DECLARE @TAB TABLE (A INT,B INT,C INT)
INSERT INTO @TAB VALUES
(100,3,50),
(100,4,60),
(101,3,70),
(102,3,70),
(102,4,80),
(102,5,90)


UPDATE      X
SET         C = NULL
FROM        @TAB X
LEFT JOIN   (
            SELECT  A,MAX(C) C 
            FROM    @TAB
            GROUP   BY A) LU ON X.A = LU.A AND X.C = LU.C
WHERE       LU.A IS NULL

SELECT * FROM @TAB

结果:

enter image description here

这种方法可以帮助你

答案 2 :(得分:1)

这个提法怎么样?

select a, b,
       (case when c = max(c) over (partition by a) then c end) as c
from table t;

我不确定你是否能更快地得到它。 a, c上的索引可能有所帮助。

答案 3 :(得分:0)

SELECT  a, b,
        CASE ROW_NUMBER() OVER (PARTITION BY a ORDER BY b DESC) WHEN 1 THEN с END c
FROM    mytable