간단히 이야기하자면, 우리는 측량 시스템이있는 외부 공급 업체와 협력하고 있습니다. 새로운 측량을 만들 때 시스템이 새로운 테이블을 만들 때 시스템이 반드시 최상으로 설계된 것은 아닙니다.
Tables
____
Library_1 -- table for Survey 1
SurveyId int
InstanceId int
Q_1 varchar(50)
Library_2 -- table for Survey 2
SurveyId int
InstanceId int
Q_2 int
Q_3 int
Q_4 varchar(255)
표는 SurveyId
이름 끝 ( Library_
)으로 생성되고 질문 열은 QuestionId
끝 ( Q_
)으로 생성됩니다. 명확히하기 위해 질문은 별도의 테이블에 저장되므로 질문 ID는 순차적이지만 각 설문 조사마다 1에서 시작하지 않습니다. 질문 열은 표에서 할당 된 ID를 기준으로합니다.
다른 시스템으로 전송하기 위해 모든 측량 테이블에서 데이터를 추출해야하는 경우를 제외하고는 쿼리하기에 충분히 단순 해 보입니다. 여기에는 문제가 발생하는 곳이 있습니다. 다른 시스템은이 유형의 구조를 처리 할 수 없습니다. 데이터를 일관성있게 사용해야합니다.
그래서 모든 Survey 테이블에서 데이터를 추출하여 다음 형식으로 저장하는 저장 프로 시저를 작성해야했습니다.
SurveyId InstanceId QNumber Response
________ __________ _______ ________
1 1 1 great
1 2 1 the best
2 9 2 10
3 50 50 test
모든 테이블의 데이터를 동일한 형식으로 사용하면 설문 테이블 및 질문 수에 관계없이 누구나 사용할 수 있습니다.
나는 작동하는 것처럼 보이는 저장 프로 시저를 작성했지만 뭔가 빠졌는지 또는 이러한 유형의 상황을 처리하는 더 좋은 방법이 있는지 궁금합니다.
내 코드 :
declare @sql varchar(max) = ''
declare @RowCount int = 1
declare @TotalRecords int = (SELECT COUNT(*) FROM SurveyData)
Declare @TableName varchar(50) = ''
Declare @ColumnName varchar(50) = ''
WHILE @RowCount <= @TotalRecords
BEGIN
SELECT @TableName = tableName, @ColumnName = columnName
FROM SurveyData
WHERE @RowCount = rownum
SET @sql = @sql +
' SELECT s.SurveyId
, s.InstanceId
, CASE WHEN columnName = ''' + @ColumnName + ''' THEN REPLACE(columnName, ''Q_'', '''') ELSE '''' END as QuestionNumber
, Cast(s.' + @ColumnName + ' as varchar(1000)) as ''Response''
FROM SurveyData t
INNER JOIN ' + @TableName + ' s' +
' ON REPLACE(t.tableName, ''Library_'', '''') = s.SurveyID ' +
' WHERE t.columnName = ''' + @ColumnName + ''''
IF @RowCount != @TotalRecords
BEGIN
set @sql = @sql + ' UNION ALL'
END
SET @RowCount = @RowCount + 1
END
exec(@sql)
샘플 데이터와 코드 로 SQL Fiddle 을 만들었습니다 .
이 유형의 쿼리를 작성해야하는 다른 방법이 있습니까? 눈에 띄는 문제가 있습니까?
불행히도, 이것에 대한 많은 미지가 있습니다 ... 우리가 가질 테이블 수와 설문 당 몇 개의 질문이 있습니까? 25-50 건의 설문 조사가 있고 2 ~ 5 개의 질문이있을 것입니다.