根据几个属性赋予新的ID

时间:2020-07-15 08:28:08

标签: sql oracle

我有一个这样的桌子

+-----+-----+-----+-----+
|att1 | att2| att3|  id |
+-----------------------+
| a   |  b  |  a  |  1  |
| b   |  c  |  c  |  2  |
| a   |  b  |  a  |  3  |
+-----------------------+

,其中包含几列和一个ID。我想用一个新的ID替换该ID,如果att1,att2和att3相等,则该ID等于:

+-----+-----+-----+-----+
|att1 | att2| att3|  id |
+-----------------------+
| a   |  b  |  a  |  1  |
| b   |  c  |  c  |  2  |
| a   |  b  |  a  |  1  |
+-----------------------+

我尝试了对属性使用带有density_rank()函数的经典合并语句,如下所示:

merge into the_table t
using (
  select att1, att2, att3, dense_rank() over (partition by att1, att2, att3 order by att1) as rnk
  from the_table 
) x on (x.att1 = t.att1 and x.att2 = t.att2 and t.att3 = x.att3)
when matched then update
   set old_id = x.new_id;

但这是行不通的,因为select att1, att2, att3, dense_rank() over (partition by att1, att2, att3 order by att1) as rnk并没有像我期望的那样为att1,att2和att3的每个分区赋予其自己的等级,而是所有东西都只获得了等级1。

我在做什么错了?

2 个答案:

答案 0 :(得分:3)

这只是另一个选择-

Demo Here

SELECT A.att1,A.att2,A.att3, B.RN id
FROM your_table A
INNER JOIN (
    SELECT att1,att2,att3,
    ROW_NUMBER() OVER (ORDER BY att1,att2,att3) RN
    FROM your_table
    GROUP BY att1,att2,att3
)B ON A.att1 = B.att1 AND A.att2 = B.att2 AND A.att3 = B.att3
ORDER BY A.Id

答案 1 :(得分:2)

回答我自己的问题:

具有等级功能的选择应如下所示,然后按预期运行

select att1, att2, att3, dense_rank() over (order by att1, att2, att3) as rnk

因此将应该获得相同排名的属性置于排序依据,而不是分区依据