仅使用SQL中的MAX函数更新重复行
我有一个这样的表,为了举例,假设,仅使用SQL中的MAX函数更新重复行,sql,oracle,sql-update,oracle12c,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
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 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
第二期
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
即使我让上述声明起作用,还有第二个问题。这里的想法是对字符串使用MAX
(或MIN
)函数为组内的所有重复设置相同的值
但不幸的是,这也不会像预期的那样起作用。为了保持一致性,理想情况下,年龄默认为最低年龄组。但是由于MAX/MIN
比较字符串的字母顺序,这将给出,例如:
- “66-74”和“65岁以下”=>MAX=“65岁以下”--最低
- “66-74”和“超过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
您可以使用case when
子句定义自定义订单,然后使用analysismax()
。这对给定的示例有效:
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 )
您的更新查询将需要逻辑选择较小的年龄(在重复的情况下),但考虑到它存储为文本,有时包含单词,这可能会导致一个具有挑战性的查询。唯一标识符的好例子!