2016-07-28 110 views
1

我在SQL Server 2008 R2中创建了一个存储过程。它执行一个数据透视表。所以,我需要为接下来的步骤提供3个新列,这些列将在此已声明的查询变量中创建。在这3列中,我必须进行计算。在SQL Server中声明的查询变量中创建新列

起初,我的存储过程的代码: 更新存储过程:

BEGIN 
    SET NOCOUNT ON; 

    DECLARE @colNo nvarchar(max) 
    DECLARE @colSum nvarchar(max) 
    DECLARE @query nvarchar(max) 

    SET NOCOUNT ON; 

    WITH vals AS (
     SELECT DISTINCT ds.No 
     FROM QRTestView ds 
    ) 

    SELECT @colNo = COALESCE(@colNo + ', ', '') + QUOTENAME(No) 
      @colSum = COALESCE(@colSum + '+ ', '') + QUOTENAME(No) 
    FROM vals 
    ORDER BY No 

    SET @query = 'SELECT *, [Bonus] + 125 as [Fee], 
        ([Bonus] + 125) * [ALL] as [Fee2] 
        FROM (
         SELECT *, 
         CASE WHEN 70-(100 - Quote) * 10 > -80 THEN 70-(100 - Quote) * 10 ELSE -70 END as [Bonus] 
         FROM (
         SELECT *, '[email protected]+' as [ALL] 
         FROM (
          SELECT 
          CAST(ISIN as CHAR(12)) As No, 
          CAST(Quote as CHAR(7)) As Quote, 
          CAST(Quote as CHAR(7)) As Q 
          FROM QRTestView 
          WHERE Datum >= @from_val and Datum <= @to_val 
         ) AS sel 
         PIVOT (
          COUNT(Q) 
          FOR No IN ('+ @colNo +') 
         ) AS p 

         UNION ALL 

         SELECT ''ALL'', *, '[email protected]+'[ALL] 
         FROM (
         SELECT 
          CAST(No as CHAR(12)) As No, 
          COUNT(CAST(Quote as CHAR(7))) As Quote 
         FROM QRTestView 
         WHERE Datum >= @from_val and Datum <= @to_val 
         GROUP BY CAST(No as CHAR(12)) 
        ) AS sel 
         PIVOT (
         MAX(Quote) 
         FOR No in ('+ @colNo +') 
        ) AS p 
        ) AS sel2 
       ) as ff 

      ORDER BY CASE WHEN Quote = ''ALL'' THEN 101 ELSE CAST(Quote as INT) END DESC' 

    EXEC sp_executesql @query, N'@from_val datetime, @to_val datetime', @from_val = @from, @to_val = @to 
END 

要理解这个问题,我会告诉你源表:

| No  | Quote | Datum 
| DE10101 | 100 | 2016-01-01 
| DE10121 | 100 | 2016-01-02 
| DE10101 | 100 | 2016-01-05 
| DE22034 | 98 | 2016-01-05 
| DE10101 | 98 | 2016-01-10 
| DE10121 | 80 | 2016-01-10 
| DE22034 | 98 | 2016-01-10 
| DE22034 | 80 | 2016-01-11 
| DE10101 | 100 | 2016-01-20 
| DE10121 | 80 | 2016-01-21 

而且目标表3附加列:

| Quote | DE10101 | DE10121 | DE22034 | ALL | Bonus | Fee | Fee2 | 
| 100 | 3 | 1 | 0 | 4 | 70 | 195 | 780 | 
| 98 | 1 | 0 | 2 | 3 | 50 | 175 | 525 | 
| 80 | 0 | 2 | 1 | 3 | -70 | 55 | 165 | 
| ALL | 4 | 3 | 3 | 10 |  |  | 1470 | 

3个新列分别是:Bonus, Fee, Fee2

计算的工作原理如下:

奖励: WHEN 70-(100 - Quote) * 10 > -80 THEN 70-(100 - Quote) * 10 ELSE -70

费用: Bonus + 125

费用2: ALL * Fee

我如何定义这3列和计算在我的查询变量存储过程中?

回答

1

您需要使用CTE

SET NOCOUNT ON; 

DECLARE @colNo nvarchar(max) 
DECLARE @SUMCols nvarchar(max) 
DECLARE @query nvarchar(max) 


SET NOCOUNT ON; 

WITH vals AS (
    SELECT DISTINCT ds.[No] 
    FROM QRTestView ds 
) 

SELECT @colNo = COALESCE(@colNo + ', ', '') + QUOTENAME([No]), 
     @SUMCols = COALESCE(@SUMCols + ', ', '') + 'SUM(' + QUOTENAME([No]) +')' 
FROM vals 
ORDER BY No 


SELECT @query = N' 
;WITH cte as (
SELECT *, 
     [Bonus] + 125 as [Fee], 
     ([Bonus] + 125) * [ALL] as [Fee2] 
FROM (
    SELECT *, 
      CASE WHEN 70-(100 - Quote) * 10 > -80 THEN 70-(100 - Quote) * 10 ELSE -70 END as [Bonus] 
    FROM (
     SELECT *, 
       '+REPLACE(@colNo,',','+')+' as [ALL] 
     FROM (
      SELECT CAST(No as CHAR(12)) As No, 
        CAST(Quote as CHAR(7)) As Quote, 
        CAST(Quote as CHAR(7)) As Q 
      FROM QRTestView 
      WHERE Datum >= @from_val and Datum <= @to_val 
      ) AS sel 
      PIVOT (
       COUNT(Q) 
       FOR No IN ('[email protected]+') 
      ) AS p 
     ) AS d 
    ) as ff 
) 

SELECT * 
FROM (
    SELECT * 
    FROM cte 
    UNION ALL 
    SELECT ''ALL'', 
      '[email protected]+' 
      SUM([ALL]), 
      NULL, 
      NULL, 
      SUM(Fee2) 
    FROM cte 
    ) as t 
ORDER BY CASE WHEN Quote = ''ALL'' THEN 101 ELSE CAST(Quote as INT) END DESC' 

EXEC sp_executesql @query, N'@from_val datetime, @to_val datetime', @from_val = @from, @to_val = @to 
+0

很不错的!是否可以将计算定义为声明的变量稍微短一些? – yuro

+0

是的,你可以。但有一个子查询。查看修改。 – gofr1

+0

在我最后一个线程中,我可以用'UNION ALL'来做到这一点吗?我的意思是这个线程 - > [链接](http://stackoverflow.com/questions/38607931/how-to-define-a-new-column-in-a-stored-procedure-query) – yuro