2016-09-01 4 views
1

코드 :TSQL - 축소 일치하는 레코드

DECLARE @T1 TABLE (ID1 INT); 
DECLARE @T2 TABLE (ID1 INT, ID2 INT, DT DATE); 

INSERT INTO @T1 (ID1) 
VALUES (1), (2); 

INSERT INTO @T2 (ID1, ID2, DT) 
    SELECT 1, 100, GETDATE() 
    UNION 
    SELECT 1, 200, GETDATE() - 1 
    UNION 
    SELECT 3, 300, GETDATE() 
    UNION 
    SELECT 4, 200, GETDATE(); 

검색어 :

SELECT 
    T1.ID1, 
    CASE 
     WHEN T2.ID2 = 100 THEN T2.DT 
    END SD, 
    CASE 
     WHEN T2.ID2 = 200 THEN T2.DT 
    END ED 
FROM 
    @T1 T1 
LEFT JOIN 
    @T2 T2 ON T1.ID1 = T2.ID1 AND T2.ID2 IN (100, 200); 

전류 출력 :

ID1 SD   ED 
---------------------------- 
1 2016-09-01 NULL 
1 NULL  2016-08-31 
2 NULL  NULL 

원하는 출력 :

ID1 SD   ED 
--------------------------- 
1 2016-09-01 2016-08-31 
2 NULL  NULL 

목표 : 키 열과 일치하는 두 행을 모두 축소하고 각 CASE 문 열을 2 개가 아닌 개별 출력으로 가져옵니다. 참고로, 실제 쿼리에서이 테이블은 크고 몇 가지 다른 테이블에 합류하고 더 많은 설명 컬럼을 선택합니다. 이 쿼리는 최소 읽기/빠름이 있어야합니다! (즉 임시 테이블/변수/CTE를 사용할 수 없습니다 모든 가능한 경우)

+0

"임시 테이블/변수/CTE를 '... 음, * 당신이 사용할 수있는 * 그렇다면 당신은 그 SQL 서버를 실현하지를 사용할 수 없습니다? 명시 적으로하지 않더라도 임시 테이블을 백그라운드로 빌드하도록 선택할 수 있습니다. 동일한 데이터베이스 내에서'select into '를 수행하지 않는다면 tempdb를 사용하고 프로세스의 경계를 정하는 것입니다. 또한 집계 할 것인지 아니면 단순히 모든 조합을 표현할 것인지 명확히하십시오. 즉, 'SD'가 '2016-01-01'이고 '2016-01-02'이 둘 다보고 싶습니까? –

답변

2

당신은 집계 함수가 필요합니다, 당신은 GROUP BY을 피하려면

SELECT T1.ID1 , 
     MIN(CASE WHEN T2.ID2 = 100 THEN T2.DT 
     END) SD , 
     MIN(CASE WHEN T2.ID2 = 200 THEN T2.DT 
     END) ED 
FROM @T1 T1 
     LEFT JOIN @T2 T2 ON T1.ID1 = T2.ID1 
          AND T2.ID2 IN (100, 200) 
GROUP BY T1.ID1; 

, 당신이 왼쪽 조인 할 수를 긴 중복 된 행이 @T2에 없다 같이

SELECT T1.ID1 , 
     T100.DT SD, 
     T200.DT ED 
FROM @T1 T1 
LEFT JOIN (SELECT * 
      FROM @T2 
      WHERE ID2 = 100) T100 
    ON T1.ID1 = T100.ID1 
LEFT JOIN (SELECT * 
      FROM @T2 
      WHERE ID2 = 200) T200 
    ON T1.ID1 = T200.ID1; 
+0

GROUP BY/DISTINCT를 피하기 위해 어쨌든 – 007

+0

@ T2에 중복이 없다고 가정하면 적절한 조건으로 두 개의 왼쪽 조인을 수행 할 수 있습니다 – Hamawi

+0

@ 007 – Lamak

0

테이블 디자인은 당신의 목표를 달성하기 위해 쿼리 스타일을 지시합니다. 그룹별로 선택하지 않았으므로 다른 옵션에는 자체 테이블 조인과 다양한 옵션이 필요합니다. 최상의 솔루션은 다음을 기반으로해야합니다.

  1. 총 쿼리 실행시 소요되는 시간입니다.
  2. 가장 좋은 쿼리 스타일. 다른 테이블 구조, 데이터 요구, 인덱스, 데이터 크기에 따라 다릅니다.
1

당신은 사용할 필요가 PIVOT :

Select * from 
(SELECT 
    T1.ID1, T2.DT, 
    CASE 
     WHEN T2.ID2 = 100 THEN 'SD' 
     WHEN T2.ID2 = 200 THEN 'ED' 
    END SDED 
FROM 
    @T1 T1 
LEFT JOIN 
    @T2 T2 ON T1.ID1 = T2.ID1 AND T2.ID2 IN (100, 200)) t 
Pivot (MAX(DT) FOR SDED in ([SD], [ED])) P