2011-08-18 3 views
-1

이 쿼리는 작동하지만 매우 비효율적 인 것처럼 보입니다. 더 좋은 방법이 있어야합니까?이 쿼리를 작성하는 더 좋은 방법이있을 수 있습니까?

내가하려는 일은 회사가 속해있는 지역을 기반으로 MarketRates 테이블에서 4 개의 다른 열을 선택하는 것입니다. 회사 테이블에 정수 1-4로 저장되는 지역은 4 개뿐입니다. 예를 들어, Territory가 "1"이면 4 개의 Southern California 열 (열 이름은 SCA *)을 선택하려고하지만 Territory가 "2"이면 4 Norhtern 캘리포니아 열을 선택하려고합니다. 열 이름은 NCA *입니다.)

테이블을 다르게 구성해야한다는 것을 알고 있지만 이것은 처리해야합니다.

MarketRates 테이블이 컬럼 (SCA = 남부 캘리포니아, NCA = 북부 캘리포니아, SNV = 남부 네바다, NAZ = 북부 애리조나가 포함

  • EndingDate - 날짜
  • SCA_MRK - 소수 (8,2)
  • SCA_RATE - 소수 (8,2)
  • SCA_COMP - 소수 (8,2)
  • SCA_NEG - 소수 (8,2)
  • NCA_MRK - 소수점 (8,2)
  • NCA_RATE - 소수점 (8,2)
  • NCA_COMP - 소수점 (8,2)
  • NCA_NEG - 소수점 (8,2)
  • SNV_MRK - 소수점 (8,2)
  • SNV_RATE - 소수점 (8,2)
  • SNV_COMP - 소수점 (8,2)
  • SNV_NEG - 소수점 (8,2)
  • NAZ_MRK - 소수점 (8,2)
  • NAZ_RATE - 십진수 (8,2)
  • NAZ_COMP - 소수 (8,2)
  • NAZ_NEG - 소수 (8,2)

이것은 내가 사용하고 현재 쿼리입니다 :

Select CompanyName 
    , case TerritoryNumber 
    when 1 then (Select top 1 coalesce(SCA_MRK,0) From MarketRates Order by EndingDate desc) 
    when 2 then (Select top 1 coalesce(NCA_MRK,0) From MarketRates Order by EndingDate desc) 
    when 3 then (Select top 1 coalesce(SNV_MRK,0) From MarketRates Order by EndingDate desc) 
    when 4 then (Select top 1 coalesce(NAZ_MRK,0) From MarketRates Order by EndingDate desc) 
    end AS MRK 
    , case TerritoryNumber 
    when 1 then (Select top 1 coalesce(SCA_RATE,0) From MarketRates Order by EndingDate desc) 
    when 2 then (Select top 1 coalesce(NCA_RATE,0) From MarketRates Order by EndingDate desc) 
    when 3 then (Select top 1 coalesce(SNV_RATE,0) From MarketRates Order by EndingDate desc) 
    when 4 then (Select top 1 coalesce(NAZ_RATE,0) From MarketRates Order by EndingDate desc) 
    end AS RATE 
    , case TerritoryNumber 
    when 1 then (Select top 1 coalesce(SCA_COMP,0) From MarketRates Order by EndingDate desc) 
    when 2 then (Select top 1 coalesce(NCA_COMP,0) From MarketRates Order by EndingDate desc) 
    when 3 then (Select top 1 coalesce(SNV_COMP,0) From MarketRates Order by EndingDate desc) 
    when 4 then (Select top 1 coalesce(NAZ_COMP,0) From MarketRates Order by EndingDate desc) 
    end AS COMP 
    , case TerritoryNumber 
    when 1 then (Select top 1 coalesce(SCA_NEG,0) From MarketRates Order by EndingDate desc) 
    when 2 then (Select top 1 coalesce(NCA_NEG,0) From MarketRates Order by EndingDate desc) 
    when 3 then (Select top 1 coalesce(SNV_NEG,0) From MarketRates Order by EndingDate desc) 
    when 4 then (Select top 1 coalesce(NAZ_NEG,0) From MarketRates Order by EndingDate desc) 
    end AS NEG 
from Company 
where CompanyID = 'THISID' 
+0

예, 있습니다 ... – SQLMason

+0

다른 필드는 NULL입니까? – JNK

+0

또한 데이터베이스 설계 재교육을 위해 자원 설계를해야한다고 생각합니다. – JNK

답변

2

당신은 단지에 있어야한다 매번 동일한 행을 참조하기 때문에 MarketRates에서 1 행을 선택하십시오. 하위 쿼리에서 선택하고 가입하면 쿼리 전체에서이를 참조 할 수 있습니다. 나는 MRK가 어떻게 생겼는지, 다른 컬럼들에 대해서도 유사한 문법/논리를 재 작성했다.

Select CompanyName 
    , case TerritoryNumber 
    when 1 then coalesce(SCA_MRK,0) 
    when 2 then coalesce(NCA_MRK,0) 
    when 3 then coalesce(SNV_MRK,0) 
    when 4 then coalesce(NAZ_MRK,0) 
    end AS MRK 
    , ...etc 
from Company 
cross join (select top 1 * from MarketRates order by EndingDate desc) MarketRates 
where CompanyID = 'THISID' 
+0

Derek에게 감사드립니다. 이것은 내가 찾고 있었던 것 중 하나 일뿐입니다. – TomL

0
DECLARE 
    @TerritoryID INT, 
    @CompanyName VARCHAR(32); 

SELECT 
    @CompanyName = CompanyName, 
    @TerritoryID = TerritoryNumber 
FROM Company 
WHERE CompanyID = 'THISID'; 

SELECT TOP 1 
    CompanyName = @CompanyName, 
    MRK = CASE @TerritoryID 
     WHEN 1 THEN SCA_MRK 
     WHEN 2 THEN NCA_MRK 
     WHEN 3 THEN SNV_MRK 
     WHEN 4 THEN NAZ_MRK END, 
    RATE = CASE @TerritoryID 
     WHEN 1 THEN SCA_RATE 
     WHEN 2 THEN NCA_RATE 
     WHEN 3 THEN SNV_RATE 
     WHEN 4 THEN NAZ_RATE END, 
    COMP = CASE @TerritoryID 
     WHEN 1 THEN SCA_COMP 
     WHEN 2 THEN NCA_COMP 
     WHEN 3 THEN SNV_COMP 
     WHEN 4 THEN NAZ_COMP END, 
    NEG = CASE @TerritoryID 
     WHEN 1 THEN SCA_NEG 
     WHEN 2 THEN NCA_NEG 
     WHEN 3 THEN SNV_NEG 
     WHEN 4 THEN NAZ_NEG END 
FROM MarketRates 
ORDER BY EndingDate DESC; 
0

당신은 하나 개의 경우 블록과 빨리 깨끗하게 유지하고 있었다. (열 유형과 일치하도록 변수 유형을 바꿀 수 있습니다.) 아래 작성된 동적 SQL을 점검하십시오. 회사 테이블이 회사 이름 열에서 '경화제'를 가지고 TerritoryNumber 열에서 2 곳 (인쇄에서 볼 수있다)

DECLARE @CompanyName varchar(50), @TerritoryNum int, @ColumnType varchar(10), @SQL VARCHAR(1000); 
SELECT @CompanyName = CompanyName ,@TerritoryNum = TerritoryNumber 
    FROM Company WHERE CompanyID = 'THISID' 
SET @ColumnType = CASE @TerritoryNum WHEN 1 THEN 'SCA_' 
            WHEN 2 THEN 'NCA_' 
            WHEN 3 THEN 'SNV_' 
            WHEN 4 THEN 'NAZ_' 
            END 

SET @SQL = ' 
SELECT 
    ''' + @CompanyName + ''' AS CompanyName, 
    COALESCE(' + @ColumnType + 'MRK,0) AS MRK, 
    COALESCE(' + @ColumnType + 'RATE,0) AS RATE, 
    COALESCE(' + @ColumnType + 'COMP,0) AS COMP, 
    COALESCE(' + @ColumnType + 'NEG,0) AS NEG 
FROM MarketRates 
' 
PRINT @SQL 
EXEC(@SQL) 

동적 쿼리는 아래와 같이 간단 할 것입니다. 이 값을 회사 테이블의 다른 숫자로 변경해보십시오. 적절한 MarketRates 열이 동적 쿼리에 표시되어야합니다.

SELECT 
    'Comp' AS CompanyName, 
    COALESCE(NCA_MRK,0) AS MRK, 
    COALESCE(NCA_RATE,0) AS RATE, 
    COALESCE(NCA_COMP,0) AS COMP, 
    COALESCE(NCA_NEG,0) AS NEG 
FROM MarketRates 
관련 문제