【问题标题】:dynamic pivot in sqlsql中的动态pivot
【发布时间】:2014-06-12 17:31:26
【问题描述】:

我有一个使用数据透视函数的以下sql 查询。我不知道我有什么错误

这个查询。请帮我解决这个问题

DECLARE @DEPT VARCHAR(MAX)            
  SELECT @DEPT=COALESCE('@DEPT+','['+DEPTID+']','['+DEPTID+'])  
  FROM DEPARTMENTDEMO  
  DECLARE @QUERY VARCHAR(MAX)  
  SET @QUERY='SELECT '+@DEPT+'    
FROM (SELECT DEPTID  
FROM DEPARTMENTDEMO     
)AS SOURCETABLE  
PIVOT  
(DEPTNAME FOR DEPTID IN ('+@DEPT+')  
)AS PIVOTTABLE'

EXEC SP_EXECUTESQL @QUERY

【问题讨论】:

  • SELECT @DEPT=COALESCE('@DEPT+','+[DEPTID]+','+[DEPTID]') 是错误的,但还有其他问题。这是一个动态的数据透视示例,从中工作:stackoverflow.com/a/23159433/3464852
  • 我需要正确的表单。我遇到了一个错误,比如“必须声明标量变量 dept”
  • 在我链接的示例中,有一个正确的方法如何获取列列表,您尝试过吗?
  • 实际上我发布的语法也是我们在课堂上得到输出的正确语法。但是当我单独尝试时,我只是错过了诸如单引号或连接运算符之类的东西。我不知道我在哪里出错了
  • 如果你坚持使用不受支持的语法,这应该可以工作:SELECT @DEPT=COALESCE(@DEPT+',['+DEPTID+']','['+DEPTID+']')。您在错误的地方引用了引号。

标签: sql sql-server pivot-table


【解决方案1】:

首先,用于创建列列表的表达式在错误的地方有一些引号:

SELECT @DEPT=COALESCE(@DEPT+',['+DEPTID+']','['+DEPTID+']')

另外,请查看here 以了解创建列列表的正确方法(它是受支持的语法并且元素的顺序得到保证)。

对于实际的 PIVOT 表达式,您必须在列上使用一些聚合。试试 MAX:

SET @QUERY= '
SELECT '+@DEPT+'    
FROM (
    SELECT DEPTID, DEPTNAME  
    FROM DEPARTMENTDEMO     
) AS SOURCETABLE  
PIVOT (
    MAX(DEPTNAME) FOR DEPTID IN ('+@DEPT+')  
) AS PIVOTTABLE'

【讨论】:

  • 不。它不会有帮助。我们不能将 max 用于 deptname。它显示错误。
  • 因为 deptname 未包含在 sourcetable 中。查看编辑
  • 优秀。它工作得很好伙计。非常感谢@dean
  • 好。如果我可能会问,您说“语法也是我们在课堂上得到输出的正确语法”——它会是哪个类?只是好奇。
  • 我公司的培训期伙计。 @dean
【解决方案2】:

前几天我只是在玩动态旋转!这是我在执行此操作时创建的功能齐全的测试脚本。尽管它基于 CROSS JOIN 示例,但它应该包含一些有用的见解。我希望您能收集一些关于如何获得所需结果的想法。

IF OBJECT_ID(N'dbo.Strikes','U') IS NOT NULL
    DROP TABLE dbo.Strikes;

CREATE TABLE dbo.Strikes(
    Dimension nvarchar(10) NOT NULL PRIMARY KEY ,
    DimVal smallint DEFAULT 0);

INSERT INTO dbo.Strikes (Dimension, DimVal)
VALUES (N'Fire',5), (N'Water',4), (N'Earth',3), (N'Air',2), (N'Spirit',1), (N'George',0);


/* Dynamic Pivot Exmple */

--declare variables and cursor
DECLARE @PvtClm varchar(MAX)
DECLARE @PTmp AS varchar(10)
DECLARE PvtCsr CURSOR FOR
    SELECT DISTINCT Dimension 
    FROM dbo.Strikes 
    ORDER BY Dimension
--open and fill pivot column string
OPEN PvtCsr
    SET @PvtClm = N'[' 
    FETCH NEXT FROM PvtCsr INTO @PTmp
    WHILE @@FETCH_STATUS = 0
        BEGIN
            SET @PvtClm = @PvtClm + RTRIM(@PTmp) + N'], ['
            FETCH NEXT FROM PvtCsr INTO @PTmp
        END
--kill cursor and finish pivot string
CLOSE PvtCsr
DEALLOCATE PvtCsr

--strip bogus end characters to finish pivot string
SET @PvtClm = LEFT(@PvtClm,(LEN(@PvtClm)-3));

--PRINT @PvtClm

--set the dynamic pivot sql string
DECLARE @DynPivot nvarchar(MAX)
SET @DynPivot = N'
WITH CrJoin AS (
    SELECT S1.Dimension AS SourceElement,
           S2.Dimension AS TargetElement,
           S1.DimVal - S2.DimVal AS Modifier
    FROM dbo.Strikes AS S1
        CROSS JOIN dbo.Strikes AS S2)

SELECT SourceElement, ' + @PvtClm + '
FROM CrJoin
PIVOT( 
    MAX(CrJoin.Modifier) 
    FOR CrJoin.TargetElement IN(' + @PvtClm + ')
    ) AS PvT;'

--PRINT @DynPivot

--run the pivot
EXEC sp_executesql @stmt = @DynPivot;


IF OBJECT_ID(N'dbo.Strikes','U') IS NOT NULL
    DROP TABLE dbo.Strikes;

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-11
    • 2021-12-29
    相关资源
    最近更新 更多