How to define a new column in a stored procedure query

匆匆过客 提交于 2019-12-24 09:30:14

问题


I have a stored procedure which realizes a pivot table. My Select statement was defined in a variable @query.

Here is the code:

BEGIN
    SET NOCOUNT ON;

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

    SET NOCOUNT ON;

    WITH vals AS (
        SELECT DISTINCT t.No
        FROM QR_Tests t
    )

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

    SET @query = 'SELECT *
                  FROM (
                    SELECT 
                        CASE WHEN GROUPING(No) = 0
                            THEN CAST(No as CHAR(12))
                        ELSE [ALL]
                        END As No,
                        CASE WHEN GROUPING(quote) = 0
                            THEN CAST(quote as CHAR(7))
                        ELSE [ALL]
                        END As Quote
                    FROM QRTestView
                    WHERE datum >= @from_val and datum <= @to_val
                    GROUP BY No, Quote WITH CUBE) AS sel
                    PIVOT (
                        COUNT(Quote)
                        FOR No IN ('+ @colNo +', [ALL])
                    ) AS p'

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

I need the following result practically:

| Quote | DE10101 | DE10121 | DE22034 | ... | ALL
|  100  |    2    |    0    |    3    | ... |  5
|   99  |    0    |    4    |    3    | ... |  7
|   98  |    5    |    1    |    7    | ... | 13
|   90  |    0    |    0    |    1    | ... |  1
|   50  |   12    |   10    |    4    | ... | 26
|  ALL  |   19    |   15    |   18    | ... | 52

I tried an example from this blog. When I execute the stored procedure, then I'm getting the error message:

invalid column name 'ALL'.

How can I define this new column for my result?


UPDATE: To understand the transformation, here the source table:

| 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

And this should be the result:

| Quote | DE10101 | DE10121 | DE22034 | ALL
| 100   |    3    |    1    |    0    |  4
|  98   |    1    |    0    |    2    |  3
|  80   |    0    |    2    |    1    |  3
| ALL   |    4    |    3    |    3    | 10   

Currently the stored procedure doesn't count the amount of quotes for every No.


回答1:


As I understand ALL is the sum of all values in this row. So you need to rewrite your SP code (based on data you provided):

BEGIN
    SET NOCOUNT ON;

    DECLARE @colNo nvarchar(max)
    DECLARE @colSum nvarchar(max) -- this will store [Column1]+[Column2] etc
    DECLARE @query nvarchar(max)

    SET NOCOUNT ON;

    WITH vals AS (
        SELECT DISTINCT t.No
        FROM QR_Tests t
    )

    SELECT  @colNo = COALESCE(@colNo + ', ', '') + QUOTENAME([No]),
            @colSum = COALESCE(@colSum + '+ ', '') + QUOTENAME([No])
    FROM vals
    ORDER BY [No]
    -- add this column here
    SET @query = 'SELECT *
                  FROM (
                    SELECT *, '+@colSum+' 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 ('+ @colNo +')
                    ) AS p
                    UNION ALL
                    SELECT ''ALL'',*, '+@colSum+'[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 d
               ORDER BY CASE WHEN Quote = ''ALL'' THEN 0 ELSE CAST(Quote as int) END DESC'

    EXEC sp_executesql @query, N'@from_val datetime, @to_val datetime', @from_val 
END



回答2:


In your case statements you need to change [ALL] to 'ALL', remembering to use two single quotes as you are building a string value:

SET @query = 'SELECT *
                  FROM (
                    SELECT 
                        CASE WHEN GROUPING(No) = 0
                            THEN CAST(No as CHAR(12))
                        ELSE ''ALL''
                        END As No,
                        CASE WHEN GROUPING(quote) = 0
                            THEN CAST(quote as CHAR(7))
                        ELSE ''ALL''
                        END As Quote
                    FROM QRTestView
                    WHERE datum >= @from_val and datum <= @to_val
                    GROUP BY No, Quote WITH CUBE) AS sel
                    PIVOT (
                        COUNT(Quote)
                        FOR No IN ('+ @colNo +', [ALL])
                    ) AS p'


来源:https://stackoverflow.com/questions/38607931/how-to-define-a-new-column-in-a-stored-procedure-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!