2012-06-07 59 views
0

我有一個表的文件夾列表,看起來像這樣:分組文件路徑

Path     Size 
C:\ParentFolder\A  123 
C:\ParentFolder\A\B  442434 
C:\ParentFolder\A\B\C 13413412 
C:\ParentFolder\D  2422341234 
C:\ParentFolder\D\E  3342 
C:\ParentFolder\D\E\F 2 
C:\ParentFolder\D\E\G 2 
... 

我在尋找SUM,GROUP BY和PATINDEX/LTRIM的某種組合/ SUBSTRING /等。這會給我回個:

Path     SumSize 
C:\ParentFolder\A  13855969 
C:\ParentFolder\D  2422344580 
... 

C:\ ParentFolder是一個已知的前綴,但A,d等。是可變文件夾名稱。我是否需要編寫一個函數來完成該功能,或者我可以使用字符串函數的組合嗎?

+0

只是一個級別? –

+0

你使用的是什麼sql-version? – Arion

+0

單層下降?是的,我想總結A和A下的所有內容,以及D下的所有內容以及其他內容。訣竅是我直到運行時才知道A和D是什麼。 版本? SQL 2008R2 – Will

回答

0

與測試集開始,

CREATE TABLE #MyTable (Folder varchar(100) not null, Size bigint not null) 

INSERT #MyTable values 
    ('C:\ParentFolder\A'  , 123) 
,('C:\ParentFolder\A\B' , 442434) 
,('C:\ParentFolder\A\B\C' , 13413412) 
,('C:\ParentFolder\D'  , 2422341234) 
,('C:\ParentFolder\D\E' , 3342) 
,('C:\ParentFolder\D\E\F' , 2) 
,('C:\ParentFolder\D\E\G' , 2) 

你首先確定你想總結一下文件夾。我這樣做,這裏由它們加載到一個臨時表:

DECLARE @Targets table (Folder varchar(100) not null) 
INSERT @Targets values 
    ('C:\ParentFolder\A') 
,('C:\ParentFolder\D') 

從這裏很容易,使用類似條款:

SELECT ta.Folder, sum(Size) TotalSize 
from @Targets ta 
    left outer join #MyTable mt 
    on mt.Folder like ta.Folder + '%' 
group by ta.Folder 

併發症可能隨之而來,如果您的文件夾包含由like子句中使用的保留字符:% _ ] [和其他一些。

+0

我認爲它會給重複使用'like'操作符時造成的結果 –

+0

這個解決方案是最乾淨的。我必須做的唯一調整是更改 INSERT @目標值 ('C:\ ParentFolder \ A') ,('C:\ ParentFolder \ D') 將一個動態查詢發現運行時的文件夾。 – Will

1
select r.Path, sum(Size) as SumSize 
from MyTable m 
inner join (
    select Path 
    from MyTable 
    where charindex('\', Path, len('C:\ParentFolder\') + 1) = 0 
) r on charindex(r.Path, m.Path, 0) = 1 
group by r.Path 

SQL Fiddle example here

+0

添加了SQL Fiddle示例。 – RedFilter

0

假設總是有最高級別的目錄中的條目(例如,如果有一個c:\xxx\yyy\zzz總是會有一個c:\xxx\yyy怎麼樣

;with roots (root) as (
    select distinct 
     path + '\' 
    from 
     thetable 
    where 
     --only include paths with 2 x \ 
     len(path) - 2 = len(replace(path, '\', '')) 
) 
select 
    roots.root, 
    sum(thetable.size) 
from 
    roots 
inner join 
    thetable on left(thetable.path + '\', len(roots.root)) = roots.root 
group by 
    roots.root 
0
select path, (select sum(Size) 
       from Paths p2 where p2.Path like p1.Path+'%') as total 
from Paths p1 
where charIndex('\',Path, len('C:\ParentFolder\')+1) = 0 
+0

你假定直接的兒童名字只有一個字符長,*「但是A,D等是可變文件夾名稱。」* – RedFilter

+0

@RedFilter你是對的,現在糾正 –

0

- - 如果該文件夾的名字始終是一個字符

select 
LEFT(folder,CHARINDEX('r\',folder)+2) as folder_group 
,SUM(size) as sumsize 
from #mytable 
GROUP BY 
LEFT(folder,CHARINDEX('r\',folder)+2) 

- - 如果該文件夾名稱具有可變長度

select 
CASE WHEN CHARINDEX('\',folder,CHARINDEX('\',folder,CHARINDEX('\',folder)+1)+1) = 0 THEN folder 
    ELSE LEFT(folder,CHARINDEX('\',folder,CHARINDEX('\',folder,CHARINDEX('\',folder)+1)+1) -1) END AS folder_group 
,SUM(size) as sumsize 
from #mytable 
GROUP BY 
CASE WHEN CHARINDEX('\',folder,CHARINDEX('\',folder,CHARINDEX('\',folder)+1)+1) = 0 THEN folder 
    ELSE LEFT(folder,CHARINDEX('\',folder,CHARINDEX('\',folder,CHARINDEX('\',folder)+1)+1) -1) END