2011-08-20 3 views
1

일부 SQL (SQL 서버 2008 용)을 만드는 데 문제가 있습니다.기존 테이블의 그룹화 된 하위 문자열에서 새 테이블 만들기

: 나는 그 ID와 함께 첫 번째 작업으로 그룹을 새로운 테이블을 구축을 위해 노력하고

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

:

나는 쉼표로 구분 작업 우선 순위 정렬 작업 테이블이

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 함수를 썼다 : 여기

GroupName: "a", TaskId: 1 
GroupName: "a", TaskId: 2 
GroupName: "a", TaskId: 4 
GroupName: "b", TaskId: 3 
는 순진, 천천히, LINQ 코드 분할 수 :

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 

을하지만 꽤 그룹화 된 관계를 참조하고 혼란 스러워요하는 방법 groking하고 있지 않다 여러 번 전화를 걸지 않아도됩니다.

의견이 있으십니까?

답변

2

목록의 첫 번째 항목 만 신경 쓰면 실제로 기능이 필요하지 않습니다. 나는이 방법을 추천 할 것이다. 또한 임시 보유를 위해 @RowSet 테이블 변수가 필요하지 않습니다. 작업 1 문자 긴 경우

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

그것은 당신이 추악한 SUBSTRING/CHARINDEX 엉망 대신 LEFT(LongTaskName, 1)을 사용할 수 있습니다, 심지어는 쉽습니다. 그러나 나는 당신의 작업 이름이 한 문자가 아닌 것으로 추측하고있다. (이 경우, 다른 사람들이 길이에 대해 가정을하지 않도록 약간 다른 데이터를 포함시켜야한다.)

이제 dbo.Tasks 행을 삽입, 업데이트 또는 삭제할 때마다 dbo.GroupedTasks을 최신 상태로 유지해야합니다. 이 두 테이블을 어떻게 동기화 할 것입니까?

더 중요한 점은 계산 된 열을 사용하거나 삽입 전에 분리하여 최우선 순위 작업을 별도로 저장하는 것입니다. 데이터를 하나로 묶는 것은 해시 테이블과 배열을 응용 프로그램 코드로 처리하는 것과 비슷하지만 데이터베이스 내부에는 긍정적 인 특성이 거의 없습니다. 처음에는 데이터를 모아서 저장하는 것보다 데이터를 추출하는 데 더 많은 시간과 노력을 소비합니다. 이것은 두 번째 테이블에 대한 필요성을 전혀 무효화 할 것입니다.

+0

와우, 좋은. 문제는 실제로 이루어집니다. 그것은 내가 일하고있는 일회성 수입 문제의 단순화 된 버전입니다, 그래서 다시하지 않아도됩니다. 그러나 당신의 훌륭한 대답과 그 잠재적 인 문제를 지적 해 주셔서 너무 감사드립니다! – teleball

0

Select ID, GroupName을 TasksWithGroupInfo로 분할하십시오 ( ).이 질문에 대한 답변이 있습니까?

관련 문제