我有这样的数据:
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中是否有更好的方法。
答案 0 :(得分:2)
更改模型是一个选项吗?如果您的任务列真的要表示层次结构,那么您应该在关系模型中正确地表示层次结构。
如果深度级别固定为3,则另一个选项可能是添加三列来独立地表示任务列的每个“部分”。
如果那不是一个选项,我认为你可以通过一系列解析字符串的CASE语句(加上SUM和GROUP BY)来实现这一点。
更新:
好的,这似乎是一个有趣的挑战,所以我提出了这个:
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
答案 1 :(得分: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)
答案 2 :(得分:1)
另一种方法是添加一些计算列,将各个任务级别分开,然后根据需要进行分组和求和。
答案 3 :(得分: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
更快? (是的,我可以测量并确切知道)