2012-03-07 3 views
1

나는이 보이는 테이블이로부터 처음 2 별개의 null 이외의 값을 포함하려고 :행을 선택하고 4 열

CREATE TABLE [Test].[dbo].[MyTest] 
(
[Id] INT NOT NULL, 
[ColA] VARCHAR(255) NULL, 
[ColB] VARCHAR(255) NULL, 
[ColC] VARCHAR(255) NULL, 
[ColD] VARCHAR(255) NULL 
); 

과의 내가 있다고 가정 해 봅시다 :

Id  ColA  ColB  ColC  ColD 
--------------------------------------- 
1  A  B  NULL  C 
2  A  A  NULL  D 
3  NULL  A  B  NULL 
4  B  B  B  B 
5  NULL  NULL  NULL  NULL 

내가 이 테이블의 모든 행을 선택하지만 ColA-ColD의 첫 번째 2 개의 고유 한 null이 아닌 값만 순서대로 선택하면됩니다. 즉, 한 행에 대해 ColA & ColB가 모두 null이 아니며 서로 구별되는 경우 해당 행에 대해 원하는 행 수가 2입니다. 내가 위에서 준 데이터를 사용하여이 쿼리에서 원하는 결과는 다음과 같습니다 행에 대한 콜라-D에 대한 모든 데이터가 NULL 인 경우 행이 선택되어 있지 않은지 것을

1, A (from ColA), B (from ColB) 
2, A (from ColA), D (from ColD) 
3, A (from ColB), B (from ColC) 
4, B (from ColA) 

알 수 있습니다. 또한 ID가 4 인 결과 행에서 볼 수있는 null이 아닌 별개의 열이 1 개인 경우에도 괜찮습니다. 2 일 필요는 없지만 이상적으로는 2가됩니다.

기본적으로 이상적입니다. ColA-ColD에서 TOP (2) DISTINCT를 얻을 수있는 곳은 어디에도 없지만 행에 TOP 및 DISTINCT 작업이 있음을 알았습니다. 어떤 도움이라도 대단히 감사합니다.

감사합니다.

답변

2

이것은 CTE와 CASE 문으로 빠른 수 있습니다 :

첫 번째 열이 반환
;WITH cte AS (
    SELECT id 
      ,COALESCE(ColA, ColB, ColC, ColD) AS col1 
      ,ColB 
      ,ColC 
      ,ColD 
    FROM tbl 
    ) 
SELECT id 
     ,col1 
     ,CASE WHEN ColB <> col1 THEN ColB 
      WHEN ColC <> col1 THEN ColC 
      WHEN ColD <> col1 THEN ColD 
      ELSE     NULL 
     END AS col2 
-- ,COALESCE(NULLIF(ColB, col1) 
--    ,NULLIF(ColC, col1) 
--    ,NULLIF(ColD, col1)) As col2 -- alt. syntax doing the same 
FROM cte 
WHERE col1 IS NOT NULL 
ORDER BY id 

(col1) 최초의 null 이외의 열과 두 번째 열은 (col2)는이 순서에서 두 x 째의 고유하지 않은 값입니다. NULL <> valueTRUE으로 평가되지 않으므로 CASE 문이 작동합니다.

하나의 고유 한 값 col2 반환 NULL가있는 경우. 모든 소스 열 NULL을 경우
col1NULL하고 행이 WHERE 절에 의해 필터링됩니다.

NULLIF()와 주석으로 대체 문법이 짧은,하지만 난 그게 더 빠를 기대하지 않습니다.

+1

'두 번째 칼럼이 두 번째 비 - null 값입니다. '- 처음에는 당신이 null을 포함 할 것이라고 생각 했었습니다 (실제 값과 구별 될 것입니다). 그리고 cte에서 null 전용 행을 필터링 할 수도 있습니다. –

+0

@ X-Zero : SQL 구문에서 "뚜렷한"점에는 'NULL'값이 포함됩니다. 나는 그에 대한 설명을 명확히했다. –

+0

Brilliant! 이것은 많은 중첩 된 COALESCE 명령문보다 더 잘 수행되어야합니다. (나 역시이 경로에서 직접 그것에 대해 생각하기 시작했고 Mark에게 대답을 정말 고맙게 생각합니다.) 정말 고마워!! – fogwolf

0

데이터베이스 디자인이 올바르지 않은 것 같습니다.

아마, 당신은 ColA,..,ColD 열이 안된다. id, type (A, .., D) 및 value이있는 두 번째 테이블이 있어야합니다. 당신이 할 수있는 구조로

쉽게는 모든 출력을 마련.

+0

답장을 보내 주셔서 감사합니다. 더 많은 문맥을 포함하지 않아서 미안합니다. 이는 대규모 프로세스의 일부입니다. 스키마를 제어 할 수없는 곳에 매핑되는 테이블이 있습니다. 이 프로세스에는 많은 임시 테이블이있는 여러 단계가 있으며 많은 양의 데이터를 처리하고 수행해야합니다. 그래서 저는 "Id"로 대표되는 각각의 개체를 반복 할 수없고 당신이 묘사하는 것처럼 테이블을 채울 수는 없습니다.기본적으로 한 테이블에서 다른 테이블로 선택하여 대량 삽입을 수행 할 수 있어야하고,이 단계에서 위에서 설명한 임시 테이블 스키마와 유사한 스키마가있는 테이블에서 선택합니다. – fogwolf

0

시도 :

select id, 
     coalesce(ColA, ColB, ColC, ColD) Result1, 
     coalesce(nullif(coalesce(ColB, ColC, ColD), coalesce(ColA, ColB, ColC, ColD)), 
       nullif(coalesce(ColC, ColD), coalesce(ColB, ColC, ColD)), 
       nullif(ColD, coalesce(ColC, ColD))) Result2 
from [Test].[dbo].[MyTest] 
+0

닫기입니다. 나는 그것을 시도했지만, ColA가 null이 아니면, 예를 들어, 거기로부터의 데이터는 결과 1과 결과 2로 채워진다. 따라서 DISTINCT 요구 사항을 다루는 것은 아닙니다. 감사! – fogwolf

+0

그뿐만 아니라 ColA의 데이터와 ColB의 데이터가 다른 경우에도 ColA의 데이터는 Result1 및 Result2에 대해 여전히 반환됩니다. – fogwolf

+0

@ user1255182 : 다시 확인하십시오.이 쿼리는 처음 게시 한 이후에 편집되었습니다. ColA가 null이 아닌 경우 Result1에 채워 지지만 ColA는 Result2에 채워지지 않습니다. 제공된 샘플 데이터에서 결과 (1, A, B)를 얻습니다. (2, A, D); (3, A, B); (4, B, NULL); (5, NULL, NULL). –

관련 문제