1

Consider I have a table with a lot of paths like:

  • \test
  • \test\file.txt
  • \test\file2.txt
  • \file3.txt
  • \test\subfolder\anotherfolder\test.txt

How would perform a SELECT query that accurately represents the folder and file structure?

  • test (folder)
  • file3.txt (file)

and then querying on the "test" folder should give

  • subfolder (folder)
  • file.txt (file)
  • file2.txt (file)

Every item in the table knows if it is a directory or a file.

7
  • Your first questions.. what do you mean exactly please? Commented Feb 7, 2011 at 20:21
  • 1
    Your expected results are unclear. Can you rephrase what it is you're looking for? Commented Feb 7, 2011 at 20:22
  • 1
    How a folder is different from a file in your table? Is it only by the fact that it always contains other files/folders? Or is it a folder because it has no name extension? I mean, if you have two rows like \folder\subfolder\a, \folder\subfolder\b, and one is a file and the other is a folder, how would you know which one is which? Commented Feb 7, 2011 at 21:57
  • you should have a precondition like 'folders always end with \' or 'files always have extension' Commented Feb 7, 2011 at 22:06
  • @Christian Sparre: Sorry, it seems I overlooked the bit Every item in the table knows if it is a directory or a file. Don't know what you mean, though. Are you talking about some IsDirectory column? Commented Feb 7, 2011 at 23:20

3 Answers 3

1

Here's a solution where it is assumed the table has a column indicating whether an item is a folder. Folder items in the table should not end with '\'.

DECLARE @dir varchar(300);
SET @dir = '\test\';

SELECT
  dir_item = CASE diritem WHEN '' THEN '.' ELSE dir_item END,
  is_folder
FROM (
  SELECT
    dir_item,
    is_folder
  FROM (
    SELECT
      dir_item = STUFF(path_item, 1, LEN(@dir), ''),
      is_folder
    FROM paths
    WHERE SUBSTRING(path, 1, LEN(@dir)) = @dir
  ) s
  WHERE CHARINDEX('\', dir_item) = 0
) s
ORDER BY is_folder DESC, dir_item;
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much Andriy, I think that will do exactly what I'm looking for.
0

see this blog about convert_anything_to_tree_structures_in_php.
The example covers a similar problem and provides a solution in php.
(doesn't mean you have to do it with php but you may adopt the idea/algorithm)

Comments

0

BW's PHP link would be good to check out, but if you'd like to stick to SQL, try this UDF. Given an input string, it will split it on a specified separator, returning one row per item.

CREATE FUNCTION dbo.Split(@Input VARCHAR(MAX), @Separator CHAR(1))
  RETURNS TABLE
AS RETURN
  WITH A AS
    (
    SELECT 1 AS Sequence, CAST(1 AS BIGINT) AS StartChar, CHARINDEX(@Separator, @Input) AS EndChar
    UNION ALL
    SELECT Sequence + 1, EndChar + 1, CHARINDEX(@Separator, @Input, EndChar + 1)
    FROM A
    WHERE EndChar > 0
    )
  SELECT
    Sequence,
    SUBSTRING(@Input, StartChar, CASE WHEN EndChar = 0 THEN LEN(@Input) - EndChar ELSE EndChar - StartChar END) AS Value
  FROM
    A

Example: SELECT * FROM dbo.Split('C:\Dir\File.ext', '\') returns:

Sequence Value
1        C:
2        Dir
3        File.ext

This isn't a complete solution, but hopefully it will help!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.