Должен быть лучший способ написать этот запрос? - PullRequest
0 голосов
/ 18 августа 2011

Этот запрос работает, но кажется ужасно неэффективным. Должен ли быть лучший способ?

То, что я пытаюсь сделать, - это выбрать 4 разных столбца из таблицы MarketRates в зависимости от того, на какой территории находится компания. В таблице Company есть только 4 территории, которые хранятся как целое число 1-4. Например, если «Территория» равна «1», то я хочу выбрать 4 столбца Южной Калифорнии (имена столбцов SCA *), но если «Территория» равна «2», то я хочу выбрать 4 столбца Северной Калифорнии ( имена столбцов NCA *) и т. д.

Я знаю, что таблицы должны быть построены по-другому, но это то, с чем я должен иметь дело.

Таблица MarketRates содержит эти столбцы (SCA = Южная Калифорния, NCA = Северная Калифорния, SNV = Южная Невада, NAZ = Северная Аризона:

  • Дата окончания - дата
  • 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'

Ответы [ 3 ]

2 голосов
/ 18 августа 2011

Вам нужно только один раз выбрать одну строку из MarketRates, поскольку вы каждый раз ссылаетесь на одну и ту же строку.Выберите его в подзапросе и присоединитесь к нему, и вы можете ссылаться на него в запросе.Я переписал, как будет выглядеть 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 голосов
/ 18 августа 2011

Вы можете держать его в чистоте и быстрее с одним блоком дела.(Вы можете заменить типы переменных в соответствии с типом данных вашего столбца.) Проверьте динамический SQL, созданный ниже.

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)

Динамический запрос (можно увидеть из печати) будет таким же простым, как показано ниже, если компаниятаблица имеет значение Comp в столбце CompanyName и 2 в столбце TerritoryNumber.Попробуйте изменить это на другие числа в таблице Company, и соответствующие столбцы 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
0 голосов
/ 18 августа 2011
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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...