2011-08-18 137 views
-1

这个查询的工作原理,但似乎非常低效。一定有更好的方法?必须有更好的方法来编写这个查询吗?

我想要做的是从MarketRates表中选择4个不同的列,根据公司所在的地区。只有4个地区,在公司表中存储为整数1-4。因此,例如,如果领土是“1”,那么我想选择4个南加州列(列名是SCA *),但如果领土是“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

其他字段为空吗? – JNK

+0

另外,我认为无论谁设计这个应该自愿参加数据库设计再教育营。 – JNK

回答

2

你应该只需要由于您每次参考同一行,因此请从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

谢谢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 
相关问题