programing

열이 존재하지 않으면 null인 경우 columnValue를 선택합니다.

sourcejob 2023. 7. 3. 22:48
반응형

열이 존재하지 않으면 null인 경우 columnValue를 선택합니다.

열이 존재하면 열 값을 선택하고 그렇지 않으면 null을 선택할 수 있는지 궁금합니다.즉, 열이 존재하지 않을 때 사건을 처리하기 위해 선택 문을 "리프트"하고 싶습니다.

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

참고로, 저는 제 데이터 모델과 디자인을 강화하는 중입니다.앞으로 몇 주 동안은 이러한 논리를 배제하고 싶지만, 데이터 모델 수정 작업은 제가 지금 해결하고자 하는 것보다 더 많은 시간이 소요되기 때문에 이 문제를 극복하고 싶습니다.

또한 한 번의 쿼리로 이 작업을 수행할 수 있습니다.그래서 나는 그런 대답을 찾고 있지 않습니다.

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

단순 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 '+@SourceName+' s
';

exec sp_executesql @sql;

실제 하위 쿼리의 경우 하위 쿼리가 해당 열 이름을 가진 무언가를 반환했는지 확인하여 동일한 값을 근사화할 수 있습니다.이를 위한 한 가지 방법은 쿼리를 실행하는 것입니다.select top 0 * into #temp from (<subquery>) s에 다음의열확다니에 있는 해 보세요.#temp.

편집:

저는 보통 그런 오래된 질문을 업데이트하지 않지만, 아래 댓글을 기반으로 업데이트합니다.하위 쿼리에서 각 행에 대해 고유한 식별자가 있는 경우 다음을 실행할 수 있습니다.

select t.. . .,  -- everything but columnthree
       (select column3   -- not qualified!
        from t t2
        where t2.pk = t.pk
       ) as column3
from t cross join
     (values (NULL)) v(columnthree);

는 하위업쿼픽니다됩.column3존재하지 않는 경우 외부 쿼리에서.그러나 이는 각 행에 고유한 식별자가 있는지 여부에 따라 크게 달라집니다.질문은 하위 쿼리에 대한 것이므로 행을 쉽게 고유하게 식별할 수 있다고 기대할 이유가 없습니다.

다른 사람들이 이미 제안했듯이, 현명한 접근 방식은 테이블 설계에 맞는 쿼리를 갖는 것입니다.

하지만 동적이 아닌 순수한 SQL에서 원하는 것을 달성하기 위한 다소 이국적인 접근 방식이 있습니다.DBA.SE에서도 유사한 문제가 게시되었습니다.열이 존재하는 경우 특정 행을 선택하는 방법 또는 열이 존재하지 않는 경우 모든 행을 선택하는 방법이 하나의 행과 하나의 열만 필요하기 때문에 더 간단합니다.당신의 문제는 더 복잡하기 때문에 질문이 더 복잡합니다.여기, 미친 접근법이 있습니다.

; 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 ;

그것은 또한 가정합니다.uniqueId하위 쿼리의 결과 집합에서 고유합니다.

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역시!) 및 마이클 에릭슨(사용)XML):
열이 있는지 확인하는 데 CASE 문을 사용할 수 없고 열에서 선택할 수 없는 이유는 무엇입니까?

동적 SQL을 사용할 수 있습니다.

먼저 기존 열을 선택한 다음 동적 쿼리를 만들어야 합니다.

DECLARE @query NVARCHAR(MAX) = '
SELECT FirstColumn, SecondColumn, '+
  (CASE WHEN exists (SELECT 1 FROM syscolumns 
  WHERE name = 'ColumnName' AND id = OBJECT_ID('TableName'))
      THEN 'ColumnName'
      ELSE 'NULL as ThreeColumn'
   END) + '
FROM TableName'

EXEC sp_executesql @query;

언급URL : https://stackoverflow.com/questions/16952442/select-columnvalue-if-the-column-exists-otherwise-null

반응형