Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Updating column according to index within group

In our databases we have a table called conditions which references a table called attributes.

So it looks like this (ignoring some other columns that aren’t relevant to the question)

id attribute_id execution_index
1 1000 1
2 1000 2
3 1000 1
4 2000 1
5 2000 2
6 2000 2

In theory the combination of attribute_id and execution_index should always be unique, but in practice they’re not, and the software ends up essentially using the id to decide which comes first between two conditions with the same execution index. We want to add a uniqueness constraint to the table, but before we do that we need to update the execution indexes. So essentially we want to group them by attribute_id, order them by execution_index then id, and give them new execution indexes so that it becomes

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

id attribute_id execution_index
1 1000 1
2 1000 3
3 1000 2
4 2000 1
5 2000 2
6 2000 3

I’m not sure how to do this without just ordering by attribute_id, execution_index, id and then iterating through incrementing the execution_index by 1 each time and resetting it to be 1 whenever the attribute_id changes. (That would work but it’d be slow and someone is going to have to run this script on several dozen databases so I’d rather it didn’t take more than a couple of seconds per database.)

Really I’d like to do something along the lines of

UPDATE c
SET c.execution_index = [this needs to be the index within the group somehow]
FROM condities c 
GROUP BY c.attribute_id
ORDER BY c.execution_index asc, c.id asc

But I don’t know how to make that actually work.

>Solution :

It looks like you can use an updatable CTE:

with cte as (
    select *, 
      Row_Number() over(partition by attribute_id order by execution_index, id) new
    from conditions
)
update cte set execution_index = new

I would suggest adding a new column and first updating that and checking the results are as expected.

Example Fiddle

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading