Как мне использовать SQL для выбора только папок верхнего уровня из таблицы папок

#sql #sql-server

#sql #sql-server

Вопрос:

У меня есть таблица со списком папок, и я хочу вернуть только папки верхнего уровня.

Например, если исходная таблица (tblFolders) содержит один столбец (Fldrs), как показано ниже:

Fldrs

 C:Folder1
C:Folder1Subfolder1
C:Folder1Subfolder2
C:Folder2Subfolder1
  

Я хотел бы вернуть:

 C:Folder1
C:Folder2Subfolder1
  

Заранее спасибо

Комментарии:

1. Какая у вас СУБД? Разные движки имеют разные возможности обработки строк

2. Если вы добавите C:Folder2Subfolder2 к образцу данные, изменится ли желаемый результат?

3. Хороший вопрос, ярлх. В этом случае я бы хотел, чтобы ответ включал оба C:Folder2Subfolder1 и C:Folder2Subfolder2 . Для папок верхнего уровня могут учитываться только папки, находящиеся в данный момент в таблице.

4. Моей СУБД является Microsoft SQL server

5. Хорошо, я пометил ваш запрос соответствующим sql-server образом.

Ответ №1:

Вы хотите выбрать все папки, для которых не существует родительской папки. Следовательно, наиболее читаемый запрос должен NOT EXISTS содержать предложение.

 select *
from tblfolders f
where not exists
(
  select null
  from tblfolders p
  where f.fldr like p.fldr   '_%'
);
  

В LIKE шаблоне символ _ представляет один символ, символ % представляет ноль или более символов. _% следовательно, один или несколько символов. Таким образом, мы удостоверяемся, что путь к дочерней папке длиннее, чем путь к родительской папке.

Комментарии:

1. Большое спасибо, Торстен. Ваш отзыв был очень полезным и информативным. При сравнении результатов ваш ответ действительно дает ожидаемые результаты, и мой опубликованный ответ имеет отмеченный вами недостаток (возвращает только верхние папки с дочерними папками), а также возвращает нежелательные папки 2-го уровня, если существуют папки 3-го уровня. Еще раз спасибо.

Ответ №2:

Я понял это, и я публикую ответ, который я нашел. Не стесняйтесь комментировать потенциальные улучшения.

 select distinct F2.fldr as TopLevelFolders 
from tblFolders F1
join tblFolders F2 on F1.fldr like F2.fldr   '%'
where F1.fldr <> F2.fldr
order by F2.fldr
  

Комментарии:

1. Хорошо, что вы приложили к этому некоторые усилия и самостоятельно нашли решение. Однако ваш запрос возвращает только верхние папки, у которых есть дочерние папки. Вы можете легко протестировать dbfiddle.uk : dbfiddle.uk /…

2. За исключением связующих таблиц, которые нам нужны для реализации отношений m: n, мое эмпирическое правило таково: объединяйте только те таблицы, данные которых я хочу иметь в своих результатах. Ограничения, с другой стороны, относятся к WHERE предложению. Для поиска я использую [NOT] IN для простых вещей и [NOT] EXISTS для более сложных условий. (Иногда поиск может быть выполнен даже с < помощью , > , <> , и = . Например where order_date = (select max(order_date) from ...) , Не присоединяться, когда в этом нет необходимости. DISTINCT это типичный показатель того, что вы объединили слишком много данных.