我的书签中有几个重复的文件夹,因为同步过程出现了问题。如果您不熟悉,Firefox会将其书签存储在硬盘上的一个名为places.sqlite的文件中。您可以通过sqlite browser之类的工具轻松访问此数据库。如您在schema中所见,moz_bookmarks表捕获书签文件夹及其所属书签的分层树结构,如下所示:
在上面的示例中,我不需要两个Cycling文件夹。我想将两个Cycling文件夹的所有后代合并到一个Cycling文件夹下,然后删除空的一个,因此我只得到了一个Cycling文件夹,但没有丢失任何内容。
第一步,这是一个查询,该查询将找到一个Cycling文件夹的所有后代:
with cte as (
select id, type, parent, title
from moz_bookmarks
where id = 2757 --id for one of the Cycling folders
union all
select b.id, b.type, b.parent, b.title
from moz_bookmarks b
join cte sub on sub.id = b.parent
)
select * from cte;
我需要找到两个文件夹的后代并将其合并。实际上,“骑自行车”并不是我唯一的重复文件夹集。我有数十种代码,因此我需要可以以类似方式遍历所有代码的代码。
答案 0 :(得分:0)
您评论中的CTE已关闭,但您没有保存锚点。要回答有关游标的问题,不,从不!每当您考虑使用游标时,几乎肯定会错。 (好的,有时候,但这确实是出于特殊目的,而不是简单的数据库更新)。
我仍然不清楚数据和您要做什么,但是此版本的CTE将查找所有没有父级(父级为null)的行,然后是其所有子级。它还会将顶级ID保存为锚点,以便您可以使用它向上滚动其他ID。
我确定这不是您需要的100%,但是应该可以使用。
然后,您可以将其保存到临时表中,并将其用作您需要做的事情的基础-将任何行的父级设置为顶级父级,设置最小创建日期或最大修改日期,或删除行完全。
全部基于集合进行操作,而不是尝试使用游标遍历任何内容。
这是您的带有锚点的CTE(已保存topID):
with cte as (
-- Find all the rows that are top level
select id as TopID, type, id, null as parent, title,
datetime(dateAdded/1000000,'unixepoch') as dateAdded,
datetime(lastModified/1000000,'unixepoch') as lastModified
from moz_bookmarks
where parent is null
union all
select cte.TopID, b.type, b.id, b.parent, b.title,
datetime(b.dateAdded/1000000,'unixepoch') as dateAdded,
datetime(b.lastModified/1000000,'unixepoch') as lastModified
from moz_bookmarks b
join cte sub on sub.id = b.parent
)
select * from cte;