【问题标题】:Retrieve column names from a different table?从不同的表中检索列名?
【发布时间】:2009-02-05 21:25:48
【问题描述】:

我有一个“datadump”表,其中包含一堆混合的性能相关数据。 类似的东西:

MachID  TestDate  MachType  Value1   Value2    ... 
00001   01/01/09  Server    15        48       
00001   01/02/09  Server    16        99       
19999   01/01/09  Switch    32        4.9880   
19999   01/02/09  Switch    32        5.8109   

诀窍在于,对于不同类型的机器,“值”列 MEAN 有不同的含义。所以我们有一个“xRef”表,如下所示:

MachType       Column   Description
Server         Value1   Users Connected
Server         Value2   % CPU _total
Switch         Value1   Number of Ports
Switch         Value2   packets/ms 
...

我知道,奇怪的结构,但我没有做到,也无法改变它。

我想以某种方式“内部连接”这些,以便我可以根据数据类型查询适当的列标题。服务器是这样的:

MachID  TestDate  MachType  Users Connected     % CPU _total    Total RAM
00001   01/01/09  Server    15                  48              4096
00001   01/02/09  Server    16                  99              4096

这用于开关:

MachID  TestDate  MachType  Number of Ports   packets/ms  Total Cumulative kb
19999   01/01/09  Switch    32                4.9880      1024547
19999   01/02/09  Switch    32                5.8109      1029450

有没有办法做到这一点,而无需对每种类型进行单独的硬编码查询?

注意:我一次只需要查询一个类型的对象。如果有帮助,我很可能只会查看单个 MachID 特定日期之间的所有结果。这是 MS SQL 2000。

谢谢!

【问题讨论】:

    标签: sql sql-server pivot


    【解决方案1】:

    这将使它们一起完成 - 如果您希望将它们全部拆分,您可以进行适当的修改。

    DECLARE @template AS varchar(max)
    DECLARE @sql AS varchar(max)
    DECLARE @column_list AS varchar(max)
    SELECT  @column_list = COALESCE(@column_list + ', ', '')
            + QUOTENAME([Description])
    FROM    xRef
    
    SET @template = ';
    WITH    up
              AS (
                  SELECT    MachID
                           ,TestDate
                           ,MachType
                           ,[COLUMN]
                           ,[Value]
                  FROM      datadump UNPIVOT ( [Value] FOR [Column] IN ([Value1], [Value2]) ) AS unpvt
                 )
                 ,ready AS (
        SELECT  machID
               ,TestDate
               ,up.MachType
               ,[Description]
               ,up.[Value]
        FROM    up
        INNER JOIN xRef
                ON xRef.machType = up.MachType
                   AND xRef.[Column] = up.[Column]
    )
    SELECT * FROM ready
    PIVOT (SUM([Value]) FOR [Description] IN ({@column_list})) AS pvt
    '
    
    machID TestDate                MachType Users Connected                         % CPU _total                            Number of Ports                         packets/ms
    ------ ----------------------- -------- --------------------------------------- --------------------------------------- --------------------------------------- ---------------------------------------
    00001  2009-01-01 00:00:00.000 Server   15.000000000000000                      48.000000000000000                      NULL                                    NULL
    00001  2009-01-02 00:00:00.000 Server   16.000000000000000                      99.000000000000000                      NULL                                    NULL
    19999  2009-01-01 00:00:00.000 Switch   NULL                                    NULL                                    32.000000000000000                      4.988000000000000
    19999  2009-01-02 00:00:00.000 Switch   NULL                                    NULL                                    32.000000000000000                      5.810900000000000
    

    【讨论】:

      【解决方案2】:

      动态 sql 选项将是(作为查询而不是写入 proc):

      declare @machtype varchar(40) --stored proc parameter?
      set @machtype = 'Switch' --or 'Server'
      
      declare @sql nvarchar(4000)
      
      set @sql = 'select
          MachID,
          TestDate,
          MachType,
          Value1 as ''' + (select [Description] from dbo.xref where machtype = @machtype and [Column] = 'Value1') + ''',
          Value2 as ''' + (select [Description] from dbo.xref where machtype = @machtype and [Column] = 'Value2') + ''',
          Value3 as ''' + (select [Description] from dbo.xref where machtype = @machtype and [Column] = 'Value3') + '''
      from 
          dbo.datadump
      where
          machtype = ''' + @machtype + ''''
      
      exec sp_executesql @sql
      

      如果你觉得这对你来说太难看了,那么将获取列名的逻辑包装在一个函数中会整理它:

      create function dbo.ColNameForDataDump(
          @machtype varchar(40),
          @column varchar(40)
      )
      RETURNS varchar(40)
      as
      begin
      
          declare @col_desc varchar(40)
          select
              @col_desc = [description]
          from
              dbo.xref
          where
              machtype = @machtype
              and [column] = @column
      
          return @col_desc
      end
      

      那么你的动态 SQL 会更像:

      declare @machtype varchar(40) --stored proc parameter?
      set @machtype = 'Switch' --or 'Server'
      
      declare @sql nvarchar(4000)
      
      set @sql = 'select
          MachID,
          TestDate,
          MachType,
          Value1 as ''' + dbo.ColNameForDataDump(@machtype, 'Value1') + ''',
          Value2 as ''' + dbo.ColNameForDataDump(@machtype, 'Value2') + ''',
          Value3 as ''' + dbo.ColNameForDataDump(@machtype, 'Value3') + '''
      from 
          dbo.datadump
      where
          machtype = ''' + @machtype + ''''
      
      exec sp_executesql @sql
      

      最后是对上面代码的传递点/评论:您提到您使用的是 SQL Server 2000,因此请确保当您必须编写一些动态 sql 将其定义为 nvarchar 并使用 sp_executesql 调用它时...从而消除了必须动态化的一些性能痛苦。

      【讨论】:

        【解决方案3】:

        创建一个表,存储该单独查询类型的每个值的标题名称。

        然后,创建一个存储过程并使用动态 SQL 填写从该表中提取的列名。

        【讨论】:

          【解决方案4】:

          由于您无法更改数据模型,我建议将表示代码放入应用程序的表示层。有一个表格,根据请求的结果为您提供要使用的列标题,然后从那里开始。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-09-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-16
            • 2018-06-11
            • 1970-01-01
            相关资源
            最近更新 更多