从现有表的分组子字符串创建新表

时间:2011-08-20 18:13:07

标签: sql sql-server linq

我在创建一些SQL时遇到了一些麻烦(对于SQL Server 2008)。

我有一个优先排序的任务表,逗号分隔的任务:

Id = 1, LongTaskName = "a,b,c"
Id = 2, LongTaskName = "a,c"
Id = 3, LongTaskName = "b,c"
Id = 4, LongTaskName = "a"
etc...

我正在尝试构建一个新表,它按照第一个任务和id:

对它们进行分组
GroupName: "a", TaskId: 1
GroupName: "a", TaskId: 2
GroupName: "a", TaskId: 4
GroupName: "b", TaskId: 3

这是天真的,慢的,linq代码:

foreach(var t in Tasks)
{
    var gt = new GroupedTasks();
    gt.TaskId = t.Id;

    var firstWord = t.LongTaskName.Split(',');
    if(firstWord.Count() > 0)
    {
        gt.GroupName = firstWord.First();
    }
    else 
    {
        gt.GroupName = t.LongTaskName;
    }
    GroupedTasks.InsertOnSubmit(gt);
}

我写了一个sql函数来做字符串拆分:

create function fn_Split(
@String nvarchar (4000),
@Delimiter nvarchar (10)
)
returns nvarchar(4000)

begin
declare @FirstComma int

set @FirstComma = charindex(@Delimiter,@String)
if(@FirstComma = 0)
return @String

return substring(@String, 0, @FirstComma)
end
go

然而,我正在坚持使用真正的sql来完成这项工作。 我可以独自得到这个小组:

SELECT dbo.fn_Split(LongTaskName, ',')
  FROM [dbo].[Tasks]
  GROUP BY dbo.fn_Split(LongTaskName, ',')

我知道我需要低头这样:

DECLARE @RowSet TABLE (GroupName nvarchar(1024), Id nvarchar(5))
insert into @RowSet
select ???
FROM [dbo].Tasks as T
INNER JOIN
(
    SELECT dbo.fn_Split(LongTaskName, ',')
      FROM [dbo].[Tasks]
      GROUP BY dbo.fn_Split(LongTaskName, ',')
) G
ON T.??? = G.???
ORDER BY ???
INSERT INTO dbo.GroupedTasks(GroupName, Id)
select * from  @RowSet

但我并不是很想知道如何引用分组关系,并且对于不得不多次调用split感到困惑。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

如果您只关心列表中的第一项,则不需要真正的功能。我会推荐这种方式。对于任何临时持有,您也不需要@RowSet表变量。

INSERT dbo.GroupedTasks(GroupName, Id)
SELECT 
    LEFT(LongTaskName, COALESCE(NULLIF(CHARINDEX(',', LongTaskName)-1, -1), 1024)),
    Id
FROM dbo.Tasks;

如果任务的长度为1个字符,则更容易,您可以使用LEFT(LongTaskName, 1)代替丑陋的SUBSTRING / CHARINDEX混乱。但我猜你的任务名称不是一个字符长(如果是这种情况,你应该包括一些变化的数据,以便其他人不会对长度做出假设)。

现在,请记住,每次插入,更新或删除dbo.GroupedTasks行时,您都必须执行此类操作以使dbo.Tasks保持最新状态。你如何保持这两个表同步?

更重要的是,您应该考虑首先单独存储最高优先级任务,方法是使用计算列或在插入之前将其分离。 Munging数据可以与应用程序代码中的哈希表和数组一起使用,但它很少在数据库中具有任何正面属性。通过将数据保存在一起,您几乎总是花费更多的时间和精力来提取数据。这将取消对第二张桌子的需求。

答案 1 :(得分:0)

在TasksWithGroupInfo中选择Id,Split(',',LongTaskName)作为GroupName 这是否回答了你的问题?