2013-06-06 1 views
22

열이있는 경우 열의 값을 선택할 수 있는지, 아니면 그렇지 않으면 null을 선택하는지 궁금합니다. 즉, 열이 존재하지 않을 때 case를 처리하기 위해 select 문을 "들어 올리"하고 싶습니다.열이 없으면 columnValue를 선택하십시오. null

SELECT uniqueId 
    , columnTwo 
    , /*WHEN columnThree exists THEN columnThree ELSE NULL END*/ AS columnThree 
FROM (subQuery) s 

참고로, 저는 데이터 모델과 디자인을 고수하는 중입니다. 나는이 논리를 앞으로 몇 주간에 배제하기를 희망하지만, 데이터 모델 수정은 내가 지금 다루고 싶은 것보다 시간이 많이 걸리는 노력이기 때문에이 문제를 넘어서고 싶습니다.

참고, 한 가지 쿼리에서이 작업을 수행 할 수 있습니다. 그래서 나는 대답을 찾고 있지 않다.

먼저 하위 쿼리에 어떤 열이 있는지 확인하십시오. 그런 다음 하위 쿼리의 열을 적절히 처리하도록 쿼리를 수정하십시오.

+1

왜 데이터 모델이 쓸데없는 것일 것이라고 가정하는 코드를 작성하고 있습니까? 이제 존재하는 열을 코딩하지 않고 ColumnThree가 데이터 모델의 영구적 인 1 급 시민이 될 때 쿼리를 수정해야하는 이유는 무엇입니까? 또한 나는 사람들에게 당신이 찾고 있지 않은 것을 말하지 않기를 강력히 권한다.명시된대로 귀하의 제한 사항을 충족시킬 수 없으며, 귀하는 그 이상의 더 나은 이유를 제시해야합니다. 저장 프로 시저에있는 것들을 캡슐화 할 수있을 때 "하나의 쿼리"에는 거의 의미가 없습니다. –

+0

@AaronBertrand 당신은 두 가지 질문을했습니다. 우선, 내 목표는 가능한 한 빨리 고품질 기능을 제공하는 것입니다. 바로 지금 필자는 필자의 기능을 올바르게 작동시키기 위해 존재할 때'ColumnThree'의 값을 필요로합니다. 그래서 솔루션이 우아하지 않더라도 컬럼이 있으면 사용할 것입니다. –

+6

@AaronBertrand 둘째, 귀하의 권고에 감사하지만 정중하게 동의하지 않습니다. 내 요구 사항을 명확하게 표현하여 사용자가 내 문제를 해결하는 솔루션을 제안하는 데 집중할 수 있도록하고, 내가 아는 답변을 작성하여 시간을 낭비하지 않도록합니다. 나는 만족스러운 대답이 아닐 것이라고 정확히 말하는 것은 솔루션을 사용하는 동안 사용자가 더 많은 가치에 집중하는 데 도움이된다고 생각합니다. –

답변

18

간단한 SQL 문으로는이 작업을 수행 할 수 없습니다. SQL 쿼리는 테이블의 모든 테이블 및 열 참조가 존재하지 않으면 컴파일되지 않습니다.

"하위 쿼리"가 테이블 참조 또는보기 인 경우 동적 SQL을 사용하여이 작업을 수행 할 수 있습니다.

동적 SQL에서, 당신은 같은 것을 할 것 : 실제 하위 쿼리를 들어

declare @sql nvarchar(max) = ' 
SELECT uniqueId, columnTwo, '+ 
    (case when exists (select * 
         from INFORMATION_SCHEMA.COLUMNS 
         where tablename = @TableName and 
          columnname = 'ColumnThree' -- and schema name too, if you like 
        ) 
      then 'ColumnThree' 
      else 'NULL as ColumnThree' 
    end) + ' 
FROM (select * from '[email protected]+' s 
'; 

exec sp_executesql @sql; 

을, 당신은 하위 쿼리가 열 이름으로 뭔가를 반환 있는지 확인하여 같은 일을 대략 수 있습니다. 한 가지 방법은 select top 0 * into #temp from (<subquery>) s 쿼리를 실행 한 다음 #temp 열을 확인하는 것입니다.

+0

나는 그렇게 생각하지 않는다. 호기심에서 동적 SQL로 어떻게하면 좋을까요? –

+0

sql 문을 문자열로 작성한 다음 exec 명령을 사용하여 작성한 문자열을 실행합니다. – liebs19

+0

그리고 동적 SQL의 내 이해에서 두 개의 쿼리를 필요로하지 않을까요? –

12

이미 제안 된 다른 방법처럼 제정 된 접근 방식은 테이블 디자인에 맞는 쿼리를 사용하는 것입니다.

(순수한, 동적이 아닌) SQL에서 원하는 것을 성취하기위한 다소 외래적인 접근법이 있습니다. 유사한 문제가 DBA.SE : How to select specific rows if a column exists or all rows if a column doesn't에 게시되었지만 하나의 행과 하나의 열이 결과로 필요하기 때문에 더 간단합니다. 문제가 더 복잡해 질수록 쿼리가 더 복잡해집니다. 그것은 또한 uniqueId이 서브 쿼리의 결과 집합의 고유 한 것으로 가정

; WITH s AS 
    (subquery)         -- subquery 
SELECT uniqueId 
    , columnTwo 
    , columnThree = 
     (SELECT (SELECT columnThree 
        FROM s AS s2 
        WHERE s2.uniqueId = s.uniqueId 
       ) AS columnThree 
     FROM (SELECT NULL AS columnThree) AS dummy 
     ) 
FROM s ; 

: 여기서, 미친 방법입니다.

SQL-Fiddle


에서 테스트 그리고 하나의 하위 쿼리와 함께 하나 이상의 열을 수있는 추가적인 장점이있는 간단한 방법 :

SELECT s.*  
FROM 
    (SELECT NULL AS columnTwo, 
      NULL AS columnThree, 
      NULL AS columnFour 
    ) AS dummy 
    CROSS APPLY 
    (SELECT 
      uniqueId, 
      columnTwo, 
      columnThree, 
      columnFour 
     FROM tableX 
    ) AS s ; 

질문도에 요청되었습니다 DBA.SE이며 @Andriy M (CROSS APPLY도 사용) 및 Michael Ericsson (XML 사용) :
Why can't I use a CASE statement to see if a column exists and not SELECT from it?

+1

이것은 꽤 멋지다! 여러 열을 사용하여이 작업을 수행 할 수있는 방법이 있지만 더 많은 조인을 수행하지 않아도됩니까? – surjikal

+0

@surjikal 내 편집을보세요! –

+0

빠른 답장을 보내 주셔서 감사합니다! 불행히도 SAP Hana를 사용하고 있으며 'CROSS APPLY'가 없습니다. 대체 솔루션에 대해 생각해 볼 수 있습니까? 이 https://stackoverflow.com/questions/26020765/sap-hana-alternative-for-cross-apply 찾았지만 작동하는지 잘 모르겠습니다. – surjikal