【问题标题】:Using pivot in SQL Server not returning desired output在 SQL Server 中使用数据透视不返回所需的输出
【发布时间】:2019-11-15 07:16:55
【问题描述】:

我有两张这样的表:

**tblTagDescription**

and  **tblDataLog**

现在我想显示任何特定组的记录,并且在一个组中,tbltagdescription 中的多个 id 可能有相同的组。 tbltagdescription 的 id 是 tblDataLog 的外键 TagDescID

这里 'Group1' 有 10 个 ID,从 1 到 10。这些 ID(从 1 到 10)在 tbldatalog 中可能有多个记录。我希望这些 ID 从 1 到作为列。为此,我使用了枢轴:

DECLARE @COlsID NVARCHAR(MAX)
DECLARE @SQL NVARCHAR(MAX)
DECLARE @Group NVARCHAR(50) = 'Group1'

IF OBJECT_ID('tempdb..##MYTABLE') IS NOT NULL 
    DROP TABLE ##MYTABLE

SELECT 
    @COlsID = COALESCE(@ColsID + '],[','') + CONVERT(NVARCHAR(5), z.TagDescID)  
FROM
    (SELECT DISTINCT TOP 50 tblDataLog.TagDescID 
     FROM tblDataLog 
     INNER JOIN tblTagDescription ON tblDataLog.TagDescID = tblTagDescription.ID 
     ORDER BY tblDataLog.TagDescID) z  

SET @COlsID='[' + @COlsID + ']'

SET @SQL='select [DATE],SHIFT, ' + @COlsID + ' into ##MYTABLE from ( select [Date], Value, 
                     (CASE  
                                WHEN ((DATEPART(hour,[DATE]))>6 and (DATEPART(hour,[DATE]))<14) THEN ''A'' 
                                WHEN ((DATEPART(hour,[DATE]))>=14 and (DATEPART(hour,[DATE]))<22) THEN ''B'' 
                                WHEN ((DATEPART(hour,[DATE]))>=22 or (DATEPART(hour,[DATE]))<6) THEN ''C'' 
                            END )AS SHIFT 

                     from tblDataLog )d pivot(max(Value) for TagDescID in (' + @COlsID + ')) piv;'

        EXEC (@SQL)

现在当我执行这个语句时,我得到一个错误:

列名“TagDescID”无效

但是tbldatalog 中有这个专栏。如何解决这个查询?

【问题讨论】:

    标签: sql sql-server sql-server-2008 pivot


    【解决方案1】:

    您需要在子查询中使用 TagDescID 列。

    DECLARE @COlsID NVARCHAR(MAX) = ''
    DECLARE @COlsAlias NVARCHAR(MAX) = ''
    DECLARE @SQL NVARCHAR(MAX)
    DECLARE @Group NVARCHAR(50) = 'Group1'
    
    SELECT 
       @COlsID = @ColsID + ',' + z.TagDescID, 
       @COlsAlias = @COlsAlias + ',' + z.TagDescID + ' AS ' + z.ReportTag   
    FROM
        (SELECT DISTINCT TOP 50 tblDataLog.TagDescID ID,  QUOTENAME(CONVERT(NVARCHAR(5), tblDataLog.TagDescID )) TagDescID, QUOTENAME(tblTagDescription.ReportTag) ReportTag 
         FROM tblDataLog 
            INNER JOIN tblTagDescription ON tblDataLog.TagDescID = tblTagDescription.ID 
         ORDER BY tblDataLog.TagDescID 
         ) z
    
    SET @COlsID= STUFF(@COlsID,1,1,'')
    SET @COlsAlias= STUFF(@COlsAlias,1,1,'')
    
    SET @SQL='select [DATE],SHIFT, ' + @COlsAlias + ' into ##MYTABLE from ( select [Date], Value, TagDescID,
                         (CASE  
                                    WHEN ((DATEPART(hour,[DATE]))>6 and (DATEPART(hour,[DATE]))<14) THEN ''A'' 
                                    WHEN ((DATEPART(hour,[DATE]))>=14 and (DATEPART(hour,[DATE]))<22) THEN ''B'' 
                                    WHEN ((DATEPART(hour,[DATE]))>=22 or (DATEPART(hour,[DATE]))<6) THEN ''C'' 
                                END )AS SHIFT 
    
                         from tblDataLog )d pivot(max(Value) for TagDescID in (' + @COlsID + ')) piv;'
    
    EXEC (@SQL)
    

    【讨论】:

    • 如果可能如何将@COlsID 中的每个值重命名为 tblTagDescription.ReportTag。如果可能,请这样做。
    • 在获取列名和动态子查询 SQL 时,您可以使用 ReportTag 列而不是 TagDescID
    • 但 ReportTag 在两列中均不可用,仅 tblTagDescription 的 Id 是 tblDataLog 中的 TgDescID 的外键
    • 我正在使用 sql server 2008 并且 'CONCAT' 不是可识别的内置函数名称
    • 我改变了连接部分。
    猜你喜欢
    • 2022-09-27
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    相关资源
    最近更新 更多