2010-01-06 24 views
0

我的數據是這樣的:如何在T-SQL中以分層格式有效地分組數據?

Task | Hours 
1.1 | 40 
2  | 40 
2.1 | 60 
2.1.1 | 15 
15.9 | 24 
16  |  5 
19.1 | 40 
19.1.1 |  8 
19.1.2 | 12 
19.2 |  6 
19.2.1 | 21 
19.2.2 | 15 
19.2.3 |  2 
19.3 | 64 

我想基於任務的前兩個級別組,產生這樣的結果:

Task | Hours 
1.1 | 40 
2  | 40 
2.1 | 75 
15.9 | 24 
16  |  5 
19.1 | 60 
19.2 | 44 
19.3 | 64 

我想16不捲起什麼在它下面,但我需要所有其他級別捲起來。這是SQL Server 2005.我通常會對小數進行分割,並以這種方式分解它,但我想知道是否有更好的方法在SQL中執行。

回答

2

正在改變模型的選擇嗎?如果您的任務列實際上是要表示層次結構,那麼您應該真正在關係模型中正確表示層次結構。

如果深度級數固定爲3,另一個選項可能是添加三列以獨立表示每個任務列的「部分」。

如果這不是一個選項,我認爲你可以通過解析字符串(加上SUM和GROUP BY)的一系列CASE語句來實現。

UPDATE:

好了,這似乎是一個有趣的挑戰,所以我想出了這個:

SELECT 
    main_task, 
    SUM(hours) 
FROM 
    (
    SELECT  
     task, 
     CASE 
      WHEN 
       LEN(task) + 1 - CHARINDEX('.', REVERSE(task)) = CHARINDEX ('.', task) THEN task 
       ELSE LEFT(task, LEN(task) + 1 - CHARINDEX('.', REVERSE(task)) - 1) 
      END main_task, 
     hours 
    FROM 
     #temp 
    ) sub 
GROUP BY 
     main_task 
+0

我認爲你在模型中存儲層次結構是正確的。我發佈了一個可能的方式 - 是否符合你的想法? – 2010-01-07 06:53:15

1

假設場任務的結構是一致的,你可以使用下面的

select left(task,4) as Task,sum(hours) as Hours 
from table 
group by left(task,4) 

這裏有一個稍微修改後的版本

select LEFT(task,charindex('.',task+'.')+1),SUM(hours) 
from test1 
group by LEFT(task,charindex('.',task+'.')+1) 
+0

我編輯我的數據,以表明它不是一致的長度。 – 2010-01-06 22:40:20

+0

我認爲你的更新答案仍然會失敗,如果中間部分,如果多個數字?如果您可以確定中間部分的長度並用該值替換「+1」,我認爲您已經擁有了它。 – 2010-01-06 23:14:03

1

另一條途徑是增加其除了打破各種任務級別的一些計算列,然後小組和總和,如你所願。

1

我在想這對我的開車回家,我想提出這樣的解決方案:

創建存儲層次結構中的表,然後做一個連接抓住任務的父。

TaskStructureTable:

task | task_group 
1  | 1 
1.1 | 1.1 
1.1.1 | 1.1 
1.1.2 | 1.1 
1.1.3 | 1.1 
1.2 | 1.2 
1.2.1 | 1.2 

然後,我可以做這樣的事情:

SELECT SUM(d.Hours) AS "Hours", t.task_group 
FROM Data d 
JOIN TaskStructureTable t ON d.Task = t.task 

認爲這將是比做CHARINDEX快? (是的,我可以測量和知道肯定)

+1

我認爲,如果您提出的建議符合您的要求,您幾乎可以將任務組視爲「類別」,而不是層級結構的一部分。你甚至不需要單獨的表格,但我會推薦一個用於參照完整性(類別查找)。是的,以這種方式構造它並在類別(_id)上放置索引肯定會比解析字符串更好。 – 2010-01-07 03:23:13

+0

如果您要更改模型,並且您正在使用sql 2008,那麼您可以使用hierarchyid數據類型進行調查。這會讓你很容易在任何級別打破你的報告。 – NotMe 2010-01-07 21:18:40

+0

不幸的是SQL Server 2005。 – 2010-01-08 04:30:24