仅使用SQL中的MAX函数更新重复行

时间:2017-08-31 11:32:55

标签: sql oracle sql-update oracle12c

我有一个这样的表,其中,假设为了一个例子,NAME是一个唯一的标识符。

NAME    AGE         VALUE
Jack    Under 65    3
Jack    66-74       5 
John    66-74       7
John    Over 75     9
Gill    25-35       11

有些NAME有多个AGE,这是不受欢迎的,因为这是由于数据的肮脏。

我的目的是更新重复项,使每个AGE中只有一个NAME。因此,所需的输出是:

NAME    AGE         VALUE
Jack    Under 65    3
Jack    Under 65    5 
John    66-74       7
John    66-74       9
Gill    25-35       11

像这样的UPDATE语句应该有效,但事实并非如此。

UPDATE table t1
SET t1.age=MAX(t1.age)
WHERE EXISTS (SELECT COUNT(t2.AGE)
              FROM table t2
              WHERE t1.NAME=t2.NAME
              GROUP BY t2.NAME
              HAVING COUNT(t2.AGE) > 1)

SQL Error: ORA-00934: group function is not allowed here

第二期

即使我上述声明有效,还有第二个问题。我们的想法是在字符串上使用MAX(或MIN)函数为组内的所有重复设置相同的值。

但不幸的是,这也不太适合。为了保持一致性,理想情况下,年龄将默认为最低年龄组。但是因为MAX/MIN比较字符串上的字母顺序,所以这会给出,例如:

  • “66-74”和“65岁以下”=> MAX =“65以下” - 最低
  • “66-74”和“Over 75”=> MAX =“超过75” - 最高

只有四个年龄组,是否可以指定自定义订单?

  • NB1:我正在使用Oracle SQL。
  • NB2:我不介意是否有办法使用SELECT而不是UPDATE语句来实现结果。

可重复的示例

SELECT 'Jack' as NAME, 'Under 65' as AGE, 3 as VALUE from dual
UNION ALL
SELECT 'Jack' as NAME, '66-74' as AGE, 5 as VALUE from dual
UNION ALL
SELECT 'John' as NAME, '66-74' as AGE, 7 as VALUE from dual
UNION ALL
SELECT 'John' as NAME, 'Over 75' as AGE, 9 as VALUE from dual
UNION ALL
SELECT 'Gill' as NAME, '25-35' as AGE, 11 as VALUE from dual

1 个答案:

答案 0 :(得分:1)

您可以使用case when子句定义自定义顺序,然后使用分析max()。这适用于给定的例子:

update t1 set age = (
    select max(age) keep (dense_rank last 
           order by case when age = 'Over 75'  then 1
                         when age = '66-74'    then 2
                         when age = 'Under 65' then 3
                         when age = '25-35'    then 4
                    end)
    from t1 tx where tx.name = t1.name )