Skip to content

Instantly share code, notes, and snippets.

@timo
Last active November 8, 2018 14:58
Show Gist options
  • Save timo/fab21b68ffef9084c4d3fc9d4822b205 to your computer and use it in GitHub Desktop.
Save timo/fab21b68ffef9084c4d3fc9d4822b205 to your computer and use it in GitHub Desktop.
can i make the update part of this query use a "with recursive" expression?
-- for testing, completely reset highest_child_id columns
update calls set highest_child_id = NULL;
-- find rows where no other row has the row's id as its parent_id
-- those shall seed the progress with initial "highest child id"
-- values
with no_children as (select id from
(select c.id as id, count(children.id) as childcount
from calls c
left join calls children on c.id == children.parent_id
group by c.id)
where childcount == 0)
update calls set highest_child_id = id where calls.id in no_children;
-- set a row's highest_child_id to
update calls set highest_child_id = (
-- the maximum of its children's highest_child_ids
select max(children.highest_child_id) as maxval
from calls children
where children.parent_id == calls.id
group by children.parent_id
)
-- unless it is already set. also, it must
where highest_child_id is null and calls.id in (
select foo.id from
-- correspond to a third set of rows
(select parents.id as id, count(children.highest_child_id) as nonnullcount, count(children.id) as allcount
from calls parents
left outer join calls children on parents.id == children.parent_id
group by parents.id) foo
-- where every child has its highest_child_id already set.
where foo.nonnullcount == foo.allcount);
-- display the results so far
select c.parent_id, c.id, c.highest_child_id, group_concat(child.id, " ")
from calls c left outer join calls child on c.id == child.parent_id
group by c.id
order by c.id;
CREATE TABLE calls(
id INTEGER PRIMARY KEY ASC,
parent_id INT,
-- can ignore everything after this point, especially the foreign key.
routine_id INT,
osr INT,
spesh_entries INT,
jit_entries INT,
inlined_entries INT,
inclusive_time INT,
exclusive_time INT,
entries INT,
deopt_one INT,
deopt_all INT,
rec_depth INT,
first_entry_time INT,
highest_child_id int,
FOREIGN KEY(routine_id) REFERENCES routines(id))
update calls set highest_child_id = NULL;
with no_children as (select id from
(select c.id as id, count(children.id) as childcount
from calls c
left join calls children on c.id == children.parent_id
group by c.id)
where childcount == 0)
update calls set highest_child_id = id where calls.id in no_children;
-- repeat this a whole bunch, or find a way to make it recursive
-- of course this currently only selects the rows that can currently have their highest_child_id set,
-- it would need to be an update statement for this to work.
select c.id as id, max(children.highest_child_id) as max_child_id
from calls c inner join calls children on c.id == children.parent_id
group by c.id;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment