Удалите дубликаты папок в местах. - PullRequest
0 голосов
/ 14 октября 2018

У меня есть несколько дубликатов папок в моих закладках из-за неправильной синхронизации.Если вы не знакомы, Firefox хранит свои закладки на жестком диске в файле place.sqlite.Вы можете легко получить доступ к этой базе данных с помощью такого инструмента, как sqlite browser .Как видно из схемы , таблица 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;

Мне нужно найти потомков для обеих папок и объединить их.И на самом деле, Cycling - это не единственный набор дубликатов папок.У меня их десятки, поэтому мне нужен код, который может провернуть их все таким же образом.

1 Ответ

0 голосов
/ 15 октября 2018

CTE в вашем комментарии близок, но вы не сохраняете опорную точку.Чтобы ответить на ваш вопрос о курсорах, НЕТ, НИКОГДА!Каждый раз, когда вы думаете об использовании курсора, вы почти наверняка ошибаетесь.(да, есть случаи, но они действительно предназначены для специальных целей, а не для простых обновлений баз).

Я до сих пор не понимаю, какие данные и что вы хотите сделать, но эта версия CTE найдетвсе строки, которые не имеют родителя (parent равен null), а затем все его дочерние элементы.Это также сохранит идентификатор верхнего уровня в качестве якоря, чтобы вы могли использовать его для свертывания других.

Я уверен, что это не на 100% от того, что вам нужно, но это должно дать хороший результат.Идея, которую вы можете использовать.

Затем вы можете сохранить это во временную таблицу и использовать ее в качестве основы для всего, что вам нужно сделать - установить родительский элемент для любых строк на родительский уровень верхнего уровня, установить min createdateили максимальное изменение даты, или полностью удалить строки.

Делайте все на основе набора, а не пытайтесь перебрать что-либо с помощью курсора.

Это будет ваш 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;
...