크로스탭 - 동일한 열에 다른 날짜(회의 1, 회의 2, 회의 3 등) 저장

StackOverflow https://stackoverflow.com/questions/1434717

  •  07-07-2019
  •  | 
  •  

문제

다양한 날짜(동적)를 추적해야 합니다.따라서 특정 작업에 대해 X개의 날짜를 추적할 수 있습니다(예: DDR1 회의 날짜, DDR2 회의 날짜, 기한 등).

내 전략은 각 날짜에 대한 설명을 저장할 하나의 테이블(DateTypeID, DateDescription)을 만드는 것이었습니다.그런 다음 기본 테이블(ID, TaskDescription, DateTypeID)을 만들 수 있습니다.따라서 모든 날짜는 하나의 열에 있으며 TypeID를 보면 해당 날짜가 무엇을 나타내는지 알 수 있습니다.문제는 그리드에 표시하는 것입니다.크로스탭 쿼리를 사용해야 한다는 것을 알고 있지만 제대로 작동할 수 없습니다.예를 들어, SQL Server 2000에서 Case 문을 사용하여 각 열 이름이 날짜 유형의 이름이 되도록 테이블을 피벗합니다.다음과 같은 테이블이 있는 경우:

날짜 유형 테이블

dateTypeId | Datedescription

 1           | DDR1
 2           | DDR2
 3           | DueDate


작업 테이블

아이디 | 작업 설명

1 | Create Design
2 | Submit Paperwork


Tasks_DateType 테이블

작업 ID | 날짜 유형 ID | 날짜

1       |     1         | 09/09/2009
1       |     2         | 10/10/2009
2       |     1         | 11/11/2009
2       |     3         | 12/12/2009


결과는 다음과 같아야 합니다.

작업 설명 | 디디르1 | DDR2 시리즈 | 만기일

Create Design     |09/09/2009 | 10/10/2009 | null
Submit Paperwork  |11/11/2009 | null       | 12/12/2009

누군가 내가 이것을 어떻게 조사할 수 있는지 아는 사람이 있다면 감사하겠습니다.각 날짜에 대한 열을 만드는 대신 이렇게 하는 이유는 사용자가 나중에 테이블에 열을 수동으로 추가하고 HTML 코드를 편집하지 않고도 원하는 만큼 많은 날짜를 추가할 수 있도록 하는 기능과 관련이 있습니다.또한 날짜를 비교하거나 향후 작업을 유형별로 표시하는 간단한 코드를 허용합니다(예:'크리에이트 디자인의 DDR1 날짜가 다가오고 있습니다' ) 누구든지 올바른 방향을 알려주시면 감사하겠습니다.

도움이 되었습니까?

해결책

다음은 데이터로 테스트 한 적절한 답변입니다. 나는 처음 두 날짜 유형 만 사용했지만 어쨌든 이것을 즉시 구축 할 것입니다.

Select 
    Tasks.TaskDescription,     
    Min(Case DateType.DateDescription When 'DDR1' Then Tasks_DateType.Date End) As DDR1,     
    Min(Case DateType.DateDescription When 'DDR2' Then Tasks_DateType.Date End) As DDR2
From
    Tasks_DateType
    INNER JOIN Tasks ON Tasks_DateType.TaskID = Tasks.TaskID
    INNER JOIN DateType ON Tasks_DateType.DateTypeID = DateType.DateTypeID
Group By
    Tasks.TaskDescription

편집하다

Van은 날짜가없는 작업이 표시되지 않는다고 언급했습니다. 이것은 정확합니다. 왼쪽 결합 (VAN에서 언급 한)을 사용하고 쿼리를 구조 조정하면 현재 필요한 것이 아니더라도 모든 작업을 반환합니다.

Select 
    Tasks.TaskDescription,     
    Min(Case DateType.DateDescription When 'DDR1' Then Tasks_DateType.Date End) As DDR1,     
    Min(Case DateType.DateDescription When 'DDR2' Then Tasks_DateType.Date End) As DDR2
From
    Tasks   
    LEFT OUTER JOIN Tasks_DateType ON Tasks_DateType.TaskID = Tasks.TaskID
    LEFT OUTER  JOIN DateType ON Tasks_DateType.DateTypeID = DateType.DateTypeID
Group By
    Tasks.TaskDescription

다른 팁

피벗 된 열이 알려지지 않은 경우 (동적), MS-SQL 2000 또는 2005에서 쿼리를 수동으로 구축해야합니다.

여기에는 저장된 프로 시저에서 동적 SQL을 실행하거나 동적 SQL로보기를 쿼리하는 것이 포함됩니다. 후자는 제가 일반적으로 진행하는 접근법입니다.

피벗을 위해, 나는 여기에 설명 된 바와 같이 사례 진술보다 로젠 슈테인 방법을 선호합니다.

http://www.stephenforte.net/permalink.aspx?guid=2b0532fc-4318-4ac0-a405-15d6d813eeb8

편집하다

LINQ-to-SQL 에서도이 작업을 수행 할 수 있지만 (적어도 LINQPAD를 통해 볼 때) 비효율적 인 코드를 방출하므로 권장하지 않습니다. 아직도 궁금한 점이 있다면 어떻게 해야하는지에 대한 예를 게시 할 수 있습니다.

피벗 연산자에 대한 개인적인 경험이 없으며 더 나은 솔루션을 제공 할 수 있습니다.

그러나 나는 과거에 사례 진술을 사용했습니다

SELECT 
    TaskDescription, 
    CASE(DateTypeID = 1, Tasks_DateType.Date) AS DDr1, 
    CASE(DateTypeID = 2, Tasks_DateType.Date) AS DDr2,
    ...
FROM Tasks 
    INNER JOIN Tasks_DateType  ON Tasks.ID = Tasks_DateType.TasksID
    INNER JOIN DateType ON Tasks_DateType.DateTypeID = DateType.DateTypeID
GROUP BY TaskDescription

이것은 작동하지만 더 많은 작업 설명이 추가 될 때마다 SQL을 변경해야하므로 이상적이지 않습니다.

편집하다:

SqlServer 2005에 피벗 키워드가 추가 된 것처럼 보입니다. 이 예 2000 년과 2005 년에 피벗 쿼리를 수행하는 방법을 보여 주지만 내 대답과 유사합니다.

버전-1: +simple, -DateType을 추가할 때마다 변경해야 합니다.따라서 동적 솔루션에는 적합하지 않습니다.

SELECT      tt.ID,
            tt.TaskDescription,
            td1.Date AS DDR1,
            td2.Date AS DDR2,
            td3.Date AS DueDate
FROM        Tasks tt
LEFT JOIN   Tasks_DateType td1
        ON  td1.TasksID = tt.ID AND td1.DateTypeID = 1
LEFT JOIN   Tasks_DateType td2
        ON  td2.TasksID = tt.ID AND td2.DateTypeID = 2
LEFT JOIN   Tasks_DateType td3
        ON  td3.TasksID = tt.ID AND td3.DateTypeID = 3

버전-2:완전히 동적입니다(몇 가지 제한 사항이 있지만 처리할 수 있습니다. Google에서 검색하면 됩니다).

동적 피벗 쿼리 생성.보다 동적 크로스탭/피벗 테이블:UDF SP 하나를 생성한 다음 이를 여러 용도로 사용할 수 있습니다.이것은 원본 게시물이며, 많은 링크와 개선 사항을 찾을 수 있습니다.

버전-3: 클라이언트 코드가 처리하도록 남겨두세요..나는 동적 데이터 집합을 반환하도록 SQL을 설계하지 않고 클라이언트(프레젠테이션 계층)에서 이를 처리하도록 설계합니다.나는 쿼리의 결과로 나오는 일부 동적 열을 처리하고 싶지 않습니다. 여기서는 그것이 정확히 무엇인지 추측해야 합니다.내가 사용하는 유일한 이유 버전-2 결과를 보고서용 테이블로 직접 제시하는 경우입니다.그 외 모든 경우에는 정말 역동적이다 데이터 클라이언트 코드를 사용합니다.예를 들어:가지고 있는 구조가 있는 경우 DueDate 필드가 필수라는 논리를 어떻게 연결합니까? DB 제약 조건을 사용할 수 없습니다.DDR1이 DDR2보다 높지 않다는 것을 어떻게 보장할 수 있습니까?CONSTRAINTS를 사용할 수 있는 데이터베이스의 별도(정적) 열이 아닌 경우 클라이언트 코드는 데이터 일관성을 검증하는 코드입니다.

행운을 빌어요!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top