我有一个实现数据透视表的存储过程。我的Select
语句是在变量@query
中定义的。
以下是代码:
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
我实际上需要以下结果:
| 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
我尝试了这个blog的例子。当我执行存储过程时,我收到错误消息:
无效的列名'ALL'。
如何为结果定义此新列?
更新: 要了解转换,请在此处输入源表:
| 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
这应该是结果:
| 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
目前,存储过程不计算每个No
的报价数量。
答案 0 :(得分:1)
在您的案例陈述中,您需要将[ALL]
更改为'ALL'
,记住在构建字符串值时使用两个单引号:
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'
答案 1 :(得分:1)
据我所知ALL
是此行中所有值的总和。因此,您需要重写SP代码(基于您提供的数据):
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