【问题标题】:SQL Server : Dynamic PivotSQL Server:动态数据透视
【发布时间】:2014-10-16 02:32:38
【问题描述】:

我发现了很多关于动态透视的文章,首先选择数据,然后运行第二个查询来进行透视,但是我有一个大型查询,我需要动态透视,但不知道如何让它工作。每个主机上的服务器都可以改变这就是为什么我需要它是动态的。可能有一个非常简单的修复方法,但我对 SQL Server 不是很好。

这是我目前的代码:

DECLARE @StartTime Date
DECLARE @EndTime Date

SET @StartTime = '2014-08-19 23:00:00'
SET @EndTime = '2014-08-22 09:21:33.557'

SELECT * 
FROM 
    (SELECT 
        [T1].[AvgMemoryUsage] AS C2, 
        CONVERT(varchar, [T1].[DateTime], 105) AS C3, 
        [T2].[Name] AS C4
     FROM 
        dbo.VIM_VMStatistics AS T1
     INNER JOIN 
        dbo.VIM_VirtualMachineNodes AS T2 ON [T1].[VirtualMachineID] = [T2].[VirtualMachineID]
     INNER JOIN 
        dbo.VIM_HostNodes AS T3 ON [T2].[HostID] = [T3].[HostID]
     LEFT JOIN 
        dbo.Nodes AS T8 ON [T3].[NodeID] = [T8].[NodeID]
     WHERE 
        [T8].[caption] = 'VMWARE-ESX01.Server.Local' 
        AND [T2].[PowerState] = 'poweredOn' 
        AND ([T2].[NodeID] IS NULL) 
        AND [T1].[DateTime] >= @StartTime 
        AND [T1].[DateTime] <= @EndTime

    UNION ALL

    (SELECT 
        [T4].[AvgMemoryUsage] AS C6, 
        CONVERT(varchar, [T4].[DateTime], 105) AS C7, 
        [T5].[Name] AS C8
     FROM 
        dbo.VIM_VMStatistics AS T4
     INNER JOIN 
        dbo.VIM_VirtualMachineNodes AS T5 ON [T4].[VirtualMachineID] = [T5].[VirtualMachineID]
     INNER JOIN 
        dbo.VIM_HostNodes AS T6 ON [T5].[HostID] = [T6].[HostID]
     LEFT JOIN 
        dbo.Nodes AS T7 ON [T5].[NodeID] = [T7].[NodeID]
     WHERE 
        [T6].[NodeID] = 1492 
        AND [T5].[PowerState] = 'poweredOn' 
        AND ([T5].[NodeID] IS NOT NULL) 
        AND [T4].[DateTime] >= @StartTime AND [T4].[DateTime] <= @EndTime)
) AS SourceTable 
PIVOT(
    AVG([c2])
    FOR [C4] IN ([server1],[server2],[server3],[server8],[server12])
) AS PivotTable

【问题讨论】:

    标签: sql sql-server dynamic pivot


    【解决方案1】:

    如果您已经了解了枢轴的工作原理,那么构建动态枢轴就相当简单了。首先,您需要一个带有分隔列的字符串来进行旋转。为此,您可以使用推荐的FOR XML PATHQUOTENAME()

    DECLARE @strPivotColumns nvarchar(max)
    SELECT @strPivotColumns = STUFF((SELECT ','  +QUOTENAME([Name]) 
                       FROM dbo.VIM_VirtualMachineNodes FOR XML PATH('')), 1, 1, '')
    

    然后你需要将原始查询保存为字符串,并将字符串与列名连接:

    DECLARE @StartTime Date
    DECLARE @EndTime Date
    
    SET @StartTime = '2014-08-19 23:00:00'
    SET @EndTime = '2014-08-22 09:21:33.557'
    
    DECLARE @DynamicPivotQuery nvarchar(2000)
    SET @DynamicPivotQuery = 
    'SELECT * FROM (
    SELECT [T1].[AvgMemoryUsage] AS C2, CONVERT(varchar, [T1].[DateTime],105) AS C3, [T2].[Name] AS C4
    FROM dbo.VIM_VMStatistics AS T1
    INNER JOIN dbo.VIM_VirtualMachineNodes AS T2 ON [T1].[VirtualMachineID] = [T2].[VirtualMachineID]
    INNER JOIN dbo.VIM_HostNodes AS T3 ON [T2].[HostID] = [T3].[HostID]
    LEFT JOIN dbo.Nodes AS T8 ON [T3].[NodeID] = [T8].[NodeID]
    WHERE [T8].[caption] = ''VMWARE-ESX01.Server.Local'' AND [T2].[PowerState] = ''poweredOn'' AND ([T2].[NodeID] IS NULL) AND [T1].[DateTime] >= @StartTime AND [T1].[DateTime] <= @EndTime
        UNION ALL
        (
            SELECT [T4].[AvgMemoryUsage] AS C6, CONVERT(varchar, [T4].[DateTime],105) AS C7, [T5].[Name] AS C8
            FROM dbo.VIM_VMStatistics AS T4
            INNER JOIN dbo.VIM_VirtualMachineNodes AS T5 ON [T4].[VirtualMachineID] = [T5].[VirtualMachineID]
            INNER JOIN dbo.VIM_HostNodes AS T6 ON [T5].[HostID] = [T6].[HostID]
            LEFT JOIN dbo.Nodes AS T7 ON [T5].[NodeID] = [T7].[NodeID]
            WHERE [T6].[NodeID] = 1492 AND [T5].[PowerState] = ''poweredOn'' AND ([T5].[NodeID] IS NOT NULL) AND [T4].[DateTime] >= @StartTime AND [T4].[DateTime] <= @EndTime
        )
    )AS SourceTable 
    PIVOT(
        AVG([c2])
        FOR [C4] IN (' + @strPivotColumns + ')
    ) AS PivotTable'
    

    然后你可以执行你的查询字符串:

    EXEC sp_executesql @DynamicPivotQuery, N'@StartTime date, @EndTime date', @StartTime = @StartTime, @EndTime = @EndTime
    

    由 STEVE 编辑:以下是现在唯一导致引用问题的原因:

    FOR [C4] IN (' + @strPivotColumns + ')
    

    错误: 消息 105,第 15 级,状态 1,第 20 行 字符串 'mad-a' 后面的非闭合引号。 消息 102,第 15 级,状态 1,第 20 行 'mad-a' 附近的语法不正确。

    【讨论】:

    • 嗨 Dimt,我已经尝试了上述方法,但只是得到错误:消息 102,级别 15,状态 1,第 12 行“VMWARE”附近的语法不正确。 Msg 137, Level 15, State 2, Line 28 必须声明标量变量“@StartTime”。
    • @Steven 啊,对不起,我省略了变量声明。您仍然需要在原始查询中声明 DECLARE @StartTime Date DECLARE @EndTime Date SET @StartTime = '2014-08-19 23:00:00' SET @EndTime = '2014-08-22 09:21:33.557'。我已经更新了我的答案。
    • @Steven 我也更改了 EXEC 语句,因为我错过了包含参数的数据类型。
    • 它似乎不喜欢 'VMWARE-ESX01.Server.local' 它看起来像是一个逃生问题,我尝试过 " 和 '' 但似乎都没有任何建议?
    • @Steven 你需要加倍你的分数,我会编辑答案
    猜你喜欢
    • 2014-07-26
    • 1970-01-01
    • 2013-02-09
    • 2018-11-22
    • 1970-01-01
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多