2016-07-20 4 views
1

나는 다음과 같이 테이블이? 요금이 0.0000 일 때마다 이전 요금으로 되돌아 가야합니다.TSQL 케이스 문

도움을 주시면 감사하겠습니다.

+3

데이터베이스 스키마를 정규화하는 것이 이상적입니다. – HardCode

+0

오른쪽. 저는 SSRS 보고서 작성자이며 제공된 내용 만 사용할 수 있습니다. 작동하도록 노력하고 있습니다. SQL 개발자는 데이터를 표준화 할 수 없습니다. -sigh- – BIReportGuy

+1

어떻게 그 일을 설명 할 수 있습니까? 'latest'를 정의하십시오 .... 최신이 0 인 후에 모든 comlumn? 이 경우에는 'Rate14'가 0이 될 것입니까? –

답변

7
Select 
    Case When Rate15 > 0 Then Rate15 
     When Rate14 > 0 Then Rate14 
     ... 
     When Rate2 > 0 Then Rate2 
     Else Rate1 
    End Rate 
From Table 
+0

무차별 대담을 통한 단순화. 때로는 이것이 최고의 대답입니다. –

+0

이 사례 명세서가 작동하려면 항상 마지막 요율 필드 (rate15)에서 가장 빠른 (rate1)로 가야합니까? 그것은 그렇게 보입니다 ... – BIReportGuy

+1

@BIGuy 확실히 'CASE' 표현식은 적중하는 첫 번째 critieria 이후에 종료됩니다. –

3

@Joe C (+1)과 완전히 일치하며 "무차별 공격"은 가장 간단한 방법입니다. 단지, 대문자 진술의 단순성을 정당화하는 것보다 다른 이유가 없다면, 이것에 대한 unpivot을 구축하는 연습을했기 때문입니다. (또한,이 큰 경우 문을 사용하여 "데이터 없음"상황에 대처하기가 훨씬 쉬워입니다.) 먼저

, 일부 샘플 데이터를 설정합니다

--DROP TABLE MyTable 
GO 

CREATE TABLE MyTable 
(
    CUSIPNumber varchar(20) not null 
    ,Year   smallint  not null 
    ,Rate1  float  not null 
    ,Rate2  float  not null 
    ,Rate3  float  not null 
    ,Rate4  float  not null 
    ,Rate5  float  not null 
    ,Rate6  float  not null 
    ,Rate7  float  not null 
    ,Rate8  float  not null 
    ,Rate9  float  not null 
    ,Rate10  float  not null 
    ,Rate11  float  not null 
    ,Rate12  float  not null 
    ,Rate13  float  not null 
    ,Rate14  float  not null 
    ,Rate15  float  not null 
) 

INSERT MyTable values 
    ('001383EA2', 16, 4.0505, 4.0510, 4.0515, 4.0520, 4.0525, 4.0530, 4.0535, 4.0550, 4.0545, 4.0550, 4.0560, 4.0570, 4.0575, 4.0585, 0) 
,('001383EA2', 15, 3.0505, 3.0510, 3.0515, 3.0520, 3.0525, 3.0530, 3.0535, 3.0550, 3.0545, 3.0550, 3.0560, 3.0570, 3.0575, 3.0585, 3.0599) 
,('001383__1', 01, 1.1, 2.2, 3.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 
,('001383_NoData', 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 

-- What we have 
SELECT * 
from MyTable 

여기에 기본 피벗 해제 문입니다. 열 (Rate2이> Rate11입니다 ...)

-- Build the unpivot statement 
SELECT * 
from (select CUSIPNumber, Year, Rate1, Rate3, Rate4, Rate5, Rate6, Rate7, Rate8, Rate9, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15 
     from MyTable) src 
unpivot (RateValue 
      for RateNumber in (Rate1, Rate3, Rate4, Rate5, Rate6, Rate7, Rate8, Rate9, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15) 
     ) unpvt 

-- Whoops! Alias the "Rate" columns, so that they can be sorted 
SELECT * 
from (select 
      CUSIPNumber 
     ,Year 
     ,Rate1 Rate01 
     ,Rate2 Rate02 
     ,Rate3 Rate03 
     ,Rate4 Rate04 
     ,Rate5 Rate05 
     ,Rate6 Rate06 
     ,Rate7 Rate07 
     ,Rate8 Rate08 
     ,Rate9 Rate09 
     ,Rate10 
     ,Rate11 
     ,Rate12 
     ,Rate13 
     ,Rate14 
     ,Rate15 
     from MyTable) src 
unpivot (RateValue 
      for RateNumber in (Rate01, Rate02, Rate03, Rate04, Rate05, Rate06, Rate07, Rate08, Rate09, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15) 
     ) unpvt 

이 데이터는 여러 번 참조 할 필요가 최신 항목을 식별하는() 최대 수 있도록, 이름/별칭이다. 이를위한 가장 간단한 방법은 그것을 만들기 위해 CTE입니다 :이

-- Make it a Common Table Expression 
WITH ctePvt 
as (select CUSIPNumber, Year, RateNumber, RateValue 
     from (select 
       CUSIPNumber 
       ,Year 
       ,Rate1 Rate01 
       ,Rate2 Rate02 
       ,Rate3 Rate03 
       ,Rate4 Rate04 
       ,Rate5 Rate05 
       ,Rate6 Rate06 
       ,Rate7 Rate07 
       ,Rate8 Rate08 
       ,Rate9 Rate09 
       ,Rate10 
       ,Rate11 
       ,Rate12 
       ,Rate13 
       ,Rate14 
       ,Rate15 
      from MyTable) src 
     unpivot (RateValue 
       for RateNumber in (Rate01, Rate02, Rate03, Rate04, Rate05, Rate06, Rate07, Rate08, Rate09, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15) 
      ) unpvt) 
select * 
from ctePvt 

, 우리는 가장 최근의 환율

-- This determines the most recent rate 
WITH ctePvt 
as (select CUSIPNumber, Year, RateNumber, RateValue 
     from (select 
       CUSIPNumber 
       ,Year 
       ,Rate1 Rate01 
       ,Rate2 Rate02 
       ,Rate3 Rate03 
       ,Rate4 Rate04 
       ,Rate5 Rate05 
       ,Rate6 Rate06 
       ,Rate7 Rate07 
       ,Rate8 Rate08 
       ,Rate9 Rate09 
       ,Rate10 
       ,Rate11 
       ,Rate12 
       ,Rate13 
       ,Rate14 
       ,Rate15 
      from MyTable) src 
     unpivot (RateValue 
       for RateNumber in (Rate01, Rate02, Rate03, Rate04, Rate05, Rate06, Rate07, Rate08, Rate09, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15) 
      ) unpvt) 
select 
    CUSIPNumber 
    ,Year 
    ,max(RateNumber) CurrentRate 
    from ctePvt 
    where RateValue <> 0 
group by 
    CUSIPNumber 
    ,Year 

그리고 그와

, 우리는 마침내 가장 최근의 값을 얻을 수를 확인할 수 있습니다 rate

-- This gest the values for the most recent rate 
WITH ctePvt 
as (select CUSIPNumber, Year, RateNumber, RateValue 
     from (select 
       CUSIPNumber 
       ,Year 
       ,Rate1 Rate01 
       ,Rate2 Rate02 
       ,Rate3 Rate03 
       ,Rate4 Rate04 
       ,Rate5 Rate05 
       ,Rate6 Rate06 
       ,Rate7 Rate07 
       ,Rate8 Rate08 
       ,Rate9 Rate09 
       ,Rate10 
       ,Rate11 
       ,Rate12 
       ,Rate13 
       ,Rate14 
       ,Rate15 
      from MyTable) src 
     unpivot (RateValue 
       for RateNumber in (Rate01, Rate02, Rate03, Rate04, Rate05, Rate06, Rate07, Rate08, Rate09, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15) 
      ) unpvt) 
select 
    cteBase.CUSIPNumber 
    ,cteBase.Year 
    ,cteBase.RateValue 
    from ctePvt cteBase 
    inner join (-- Most recent rate per item 
       select 
        CUSIPNumber 
       ,Year 
       ,max(RateNumber) CurrentRate 
       from ctePvt 
       where RateValue <> 0 
       group by 
        CUSIPNumber 
       ,Year) cteRecent 
    on cteRecent.CUSIPNumber = cteBase.CUSIPNumber 
    and cteRecent.Year = cteBase.Year 
    and cteRecent.CurrentRate = cteBase.RateNumber 

속도 값이없는 항목에 대해 행을 반환하지 않습니다. 해결할 수있는 몇 가지 방법이 있지만 충분합니다.

대박 진술을 사용하셨습니까?

3

아래보다 간결한 접근 방식이 있지만 완전히 확장 된 CASE 버전이 더 명확하고 효율적입니다.

Select COALESCE(NULLIF(Rate15,0), 
       NULLIF(Rate14,0), 
       NULLIF(Rate13,0), 
       ... 
       NULLIF(Rate3,0), 
       NULLIF(Rate2,0), 
          Rate1 
       ) AS Rate 
From Table 
+0

나는 이것도 생각하고 있었는데, 기본 데이터가 0 대신에 널 값을 가지면 특히 편리했을 것이다. –