SQL Server - 使用声明的变量来标识数据透视表列

时间:2014-08-08 18:51:13

标签: sql sql-server

我创建了一个SQL Server Pivot查询,用于透视并显示符合某些参数的贷方的费率和价格。这个查询工作得很好,但问题是我必须手动识别并输入我想要为我创建的每个单独查询使用的速率(它成为列名)。

我希望能够简单地声明一个搜索表的变量,并确定该产品分组的最低费率,然后使用该变量来标识我想要转向的列。

我创建了变量并且它成功找到了正确的速率,但是当我将“(4),[4.125],...”中的列(速率)名称替换为“[@RateMIN],[ @ RateMIN2],...等“我收到一个错误抱怨:”将数据类型nvarchar转换为float时出错。“

奇怪的是,Rate列已经是float了,那么为什么要尝试将它从nvarchar转换为float?我认为我不考虑或不理解枢轴功能的某些方面?

按请求,添加现在有效的查询,但没有变量。

DECLARE @ProductX as VARCHAR(MAX)
DECLARE @statenameX as VARCHAR(MAX)
DECLARE @purposeTypeX as VARCHAR(MAX)
DECLARE @ficoX as float
DECLARE @loanSizeX as float
DECLARE @LTVx as float

SET @ProductX = '30YearFixedProduct'
SET @statenameX = 'CA'
SET @purposeTypeX = 'Purchase'
SET @ficoX = 740
SET @loanSizeX = 900000
SET @LTVx = 70

SELECT
LenderName as 'Lenders',
[4] as '4.000%',
[4.125] as '4.125%',
[4.25] as '4.250%',
[4.375] as '4.375%',
[4.5] as '4.500%',
[4.625] as '4.625%',
[4.75] as '4.750%',
[4.875] as '4.875%'




from
(
    SELECT 
    [LenderName],[Price],[Rate]
    FROM
    PricingTable

    WHERE
    Product = @ProductX AND
    statename = @statenameX AND
    PurposeType = @purposeTypeX AND
    FICO = @ficoX AND 
    LoanSize = @loanSizeX AND
    LTV = @LTVx


) as SourceTable2

Pivot
(
avg(Price) for Rate IN ([4],[4.125],[4.25],[4.375],[4.5],[4.625],[4.75],[4.875])
)
as PivotTable2

Order by 
CASE WHEN [4.125] is null then 1 else 0 end, 
[4.125]

添加查询,我尝试添加变量@RateMin并使用它来定义其中一个列名。下面的查询是给我错误的查询。

DECLARE @ProductX as VARCHAR(MAX)
DECLARE @statenameX as VARCHAR(MAX)
DECLARE @purposeTypeX as VARCHAR(MAX)
DECLARE @ficoX as float
DECLARE @loanSizeX as float
DECLARE @LTVx as float

DECLARE @rateMIN as float
SET @rateMIN = (SELECT min([rate])   FROM PricingTable  WHERE 
            Product = @ProductX AND 
            statename = @statenameX AND 
            PurposeType = @purposeTypeX AND
            FICO = @ficoX AND 
            LoanSize = @loanSizeX AND
            LTV = @LTVx)


SET @ProductX = '30YearFixedProduct'
SET @statenameX = 'CA'
SET @purposeTypeX = 'Purchase'
SET @ficoX = 740
SET @loanSizeX = 900000
SET @LTVx = 70

SELECT
LenderName as 'Lenders',
[@rateMIN] as '4.000%',
[4.125] as '4.125%',
[4.25] as '4.250%',
[4.375] as '4.375%',
[4.5] as '4.500%',
[4.625] as '4.625%',
[4.75] as '4.750%',
[4.875] as '4.875%'

from
(
    SELECT 
    [LenderName],[Price],[Rate]
    FROM
    PricingTable

    WHERE
    Product = @ProductX AND
    statename = @statenameX AND
    PurposeType = @purposeTypeX AND
    FICO = @ficoX AND 
    LoanSize = @loanSizeX AND
    LTV = @LTVx


) as SourceTable2

Pivot
(
avg(Price) for Rate IN ([@rateMIN],[4.125],[4.25],[4.375],[4.5],[4.625],[4.75],[4.875])
)
as PivotTable2

Order by 
CASE WHEN [4.125] is null then 1 else 0 end, 
[4.125]

1 个答案:

答案 0 :(得分:0)

好的,我终于明白了,所以我回到这里发布结果,以便其他人可以从我的经验中受益。

我学到的最重要的事情是,在创建和测试动态SQL时,不要试图简单地执行查询。在构建此类查询时,您需要先打印它。然后,您将获取结果并将其复制并粘贴到新的查询窗口中。这将允许您查看实际连接的内容以及遇到问题的位置!我没有在网上看到这个推荐。

我遇到的第二个最大的问题是我需要对我的列名采取不同的方法。我必须在互联网上找到的教程中使用QUOTENAME的COALESCE语句。这一系列语句在我的定价表中找到rate的可用值,然后将它们转换为我用来构建我的SQL语句的文本。

与我所做的其他编程相比,我仍然觉得必须使用动态SQL有点倒退。为什么我需要将整个select语句转换为文本?为什么不简单地保持原样,然后将变量转换为文本,然后运行SQL?我将不得不考虑一下这一点。我不能理解SQL如何处理/运行查询的复杂性。

这是完成的动态SQL查询。请注意,我正在打印结果,但我可以轻松地执行它:

DECLARE @ProductX as VARCHAR(MAX)
DECLARE @stateX as VARCHAR(MAX)
DECLARE @PurposeX as VARCHAR(MAX)
DECLARE @ficoX as NVARCHAR(MAX)
DECLARE @loanSizeX as NVARCHAR(MAX)
DECLARE @LTVx as NVARCHAR(MAX)
Declare @RateX NVARCHAR(MAX)
Declare @RateX_2 NVARCHAR(MAX)
declare @SQL as NVARCHAR(MAX)
DECLARE @Columns as VARCHAR(MAX)

SET @ProductX = '30YearFixedProduct'
SET @stateX = 'CA'
SET @PurposeX = 'Purchase'
SET @ficoX = 740
SET @loanSizeX = 900000
SET @LTVx = 70

SELECT @Columns = COALESCE(@Columns + ',','') + QUOTENAME(RATE)
                    FROM
                      (
                      SELECT DISTINCT RATE
                      FROM PricingTable WHERE
                        Product = @ProductX AND
                        state = @stateX AND
                        Purpose = @PurposeX AND
                        FICO = @ficoX AND 
                        LoanSize = @loanSizeX AND
                        LTV = @LTVx) 
                       AS TableNew


set @RateX = (select min(rate) from PricingTable    WHERE
                        Product = @ProductX AND
                        state = @stateX AND
                        Purpose = @PurposeX AND
                        FICO = @ficoX AND 
                        LoanSize = @loanSizeX AND
                        LTV = @LTVx)

set @RateX_2 = cast(@RateX as float) + .125





SET @SQL = '
SELECT
Lenders,
'+@Columns+'


from
(
    SELECT 
    [Lenders],[Price],[Rate]
    FROM
    PricingTable

    WHERE
    Product = '''+@ProductX+''' AND
    state = '''+@stateX+''' AND
    Purpose = '''+@PurposeX+''' AND
    FICO = '''+@ficoX+''' AND 
    LoanSize = '''+@loanSizeX+''' AND
    LTV = '''+@LTVx+'''


) as SourceTable2

Pivot
(
avg(Price) for Rate IN ('+@Columns+')
)
as PivotTable2


'
PRINT (@SQL)