我当前正在将MS Access数据库移至SQL Server。我有一个cross-tab query
,我需要转换为Pivot table
。
Pivot table
将位于sproc
中,为month
和year
提供参数。这些参数放在WHERE
的{{1}}子句中。
SQL:
subquery
我在SELECT IDNbr, [Name]
FROM (SELECT a1.IDNbr , a2.[CustName] as [Name] , a1.BalDate, a1.Balance
FROM IDTable a1 INNER JOIN CustTable a2 ON (a1.IDNbr = a2.IDNbr)
WHERE MONTH(a1.BalDate) = @month AND YEAR(a1.BalDate) = @year) as d1
PIVOT (
SUM(Balance)
For Balance in ([BalDate]) --Error: see below
) piv;
部分遇到的错误是:
PIVOT运算符中指定的列名称“ BalDate”与PIVOT参数中的现有列名称冲突。
我也收到错误消息:
为“ piv”指定了“ BalDate”列。
当前数据:
Pivot
所需数据:
Customer | BalDate | Balance
----------+-------------+--------
Customer1 | 1/01/2017 | 0.00
Customer1 | 1/02/2017 | 0.00
Customer1 | 1/03/2017 | 0.00
Customer1 | 1/04/2017 | 0.00
.... | .... | ....
主要问题:我该如何纠正| Customer | 01/01/2017 | 01/02/2017 | 01/03/2017 | 01/04/2017 | 01/05/2017 | 01/06/2017 | 01/07/2017 | 01/08/2017 | 01/09/2017 | 01/10/2017 | ....
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Customer1 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | ....
| Customer2 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | ....
| Customer3 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | ....
中的错误?
次要问题:我如何将Pivot Table
提升到Current data
?
我仍然是SQL和SQL Server的初学者,所以如果答案很明显,我深表歉意。
在此先感谢您的帮助和建议!而且,我将很乐意尝试澄清任何似乎令人困惑或不清楚的内容!
我引用过的帖子,并试图将其应用于我的情况:
Column name specified in the pivot operator conflicts
Column was specified multiple times
答案 0 :(得分:1)
在MS Sql Server中,您需要为此使用动态sql。
首先使用日期计算一个变量。
然后将其用于动态查询的字符串中。
您可以在{em> rextester 上对其进行here测试
DECLARE @Dates NVARCHAR(max);
SELECT @Dates = CONCAT(@Dates + ', ', QUOTENAME(BalDate))
FROM IDTable
WHERE YEAR(BalDate) = @year
AND MONTH(BalDate) = @month
GROUP BY BalDate
ORDER BY BalDate;
DECLARE @DynSql NVARCHAR(max);
SET @DynSql = 'SELECT *
FROM
(
SELECT a1.IDNbr, a2.[CustName] as [Name], a1.BalDate, a1.Balance
FROM IDTable a1
INNER JOIN CustTable a2 ON (a1.IDNbr = a2.IDNbr)
WHERE MONTH(a1.BalDate) = @month
AND YEAR(a1.BalDate) = @year
) as src
PIVOT (
SUM(Balance)
FOR BalDate IN ('+ @Dates +')
) pvt';
DECLARE @Params NVARCHAR(500) = N'@year INT, @month INT';
-- SELECT @DynSql AS DynSql;
EXECUTE sp_executesql @DynSql, @Params, @year = @year, @month = @month;
答案 1 :(得分:1)
您可以尝试对BalDate
使用动态SQL。
由于查询具有参数,因此您可以尝试使用sp_executesql并在执行语法中附加参数。
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(a1.BalDate)
FROM IDTable a1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT *
FROM (
SELECT a1.IDNbr , a2.[CustName] as [Name] , a1.BalDate, a1.Balance
FROM IDTable a1 INNER JOIN CustTable a2 ON (a1.IDNbr = a2.IDNbr)
WHERE MONTH(a1.BalDate) = @month AND YEAR(a1.BalDate) = @year
) as d1
PIVOT (
SUM(Balance)
For Balance in ('+ @cols +') --Error: see below
) piv'
EXECUTE sp_executesql @query, N'@year INT,@month INT',
@year = @year,
@month = @month
答案 2 :(得分:1)
听起来像是需要动态枢轴,
首先,您必须选择要在数据透视表中使用的所有日期, 日期必须为QuoteName格式,即[Date],否则枢轴将无法理解。
DECLARE @Days NVarchar(MAX)
SEt @Days = STUFF((SELECT ',' + QUOTENAME(a1.BalDate)
FROM IDTable a1
group by a1.BalDate
order by a1.BalDate
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
Select @Days
然后,您必须构建一个动态枢纽,像这样。
DECLARE @FinalQuery NVARCHAR (MAX)
SET @FinalQuery = 'SELECT *
INTO #ToReportOn
FROM
(SELECT a1.IDNbr , a2.[CustName] as [Name] , a1.BalDate, a1.Balance
FROM IDTable a1 INNER JOIN CustTable a2 ON (a1.IDNbr = a2.IDNbr)
WHERE MONTH(a1.BalDate) = @month AND YEAR(a1.BalDate) = @year) as d1
) A
PIVOT
(
SUM(Balance)
For BalDate in ('+@Days +')
) B
ORDER BY document_group
SELECT * FROM #ToReportOn
'
--EXECUTE(@FinalQuery)
PRINT @FinalQuery
我没有测试。但是我认为动态枢纽是解决您的问题的方法。