【问题标题】:SQL Server : dynamically create columns from an ID column linking to another tableSQL Server:从链接到另一个表的 ID 列动态创建列
【发布时间】:2018-12-06 18:46:53
【问题描述】:

我正在尝试根据链接到另一个表的列名的 ID 动态创建列。 (我不知道这是否可能用于网页上的 ssrs 报告和网格视图。)

看看下面的例子 - “当前表”是它现在的样子。我对每个名字都有一个专栏。我已经创建了定义表。我想让当前表看起来像建议的表,并“创建”选择中的列或使用定义表的名称,使其看起来像现在一样。

【问题讨论】:

  • 数据图像对您寻求帮助的志愿者没有帮助。样本数据应按原样提供,text;甚至更好的 DDL 和 DML 语句。看看here

标签: sql sql-server sql-server-2008-r2


【解决方案1】:

这是一种无需实际使用动态 SQL 即可“动态”取消透视数据的方法。

显然 Gordon 的性能更高,但在这里,您不必声明列。

示例

Select  D.id
       ,[count] = C.Value
       ,A.ts
 From  CurrentTable A
 Cross Apply ( values (cast((Select A.* for XML RAW) as xml))) B(XMLData)
 Cross Apply (
                Select Item = a.value('local-name(.)','varchar(100)')
                      ,Value = a.value('.','int')    -- Use appropriate type
                 From  B.XMLData.nodes('/row')  as C1(n)
                 Cross Apply C1.n.nodes('./@*') as C2(a)
                 Where a.value('local-name(.)','varchar(100)') not in ('ts','OtherColToExclude')
             ) C
 Join   definition D on C.item=D.Name

返回

id  count   ts
1   5       2018-12-06
2   88      2018-11-01
2   18      2018-10-18
3   32      2018-10-27
4   6       2018-10-27

【讨论】:

    【解决方案2】:

    这是一个非常奇怪的数据结构。这是一种方法:

    select d.id as definition,
           coalesce(c.p1, c.p2, c.p3, c.p4) as "count",
           c.ts
    from current_table c join
         definition d
         on (d.name = 'p1' and p1 is not null) or
            (d.name = 'p2' and p2 is not null) or
            (d.name = 'p3' and p3 is not null) or
            (d.name = 'p4' and p4 is not null) ;
    

    【讨论】:

      【解决方案3】:

      您也可以尝试使用 unpivot 来满足您的要求。更多详情可以参考这篇文章:https://docs.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-2017

      ----drop table [current_table] 
      ----drop table [definition] 
      create table [current_table] 
      (p1 int,
      p2 int,
      p3 int,
      p4 int,
      ts date )
      insert into [current_table] values
      (5,null,null,null,'20181206'),
      (null,88,null,null,'20181101'),
      (null,18,null,null,'20181018'),
      (null,null,32,null,'20181027'),
      (null,null,null,6,'20181014')
      
      create table [definition] 
      (id int,
      name varchar(5) )
      insert into [definition] values 
      (1,'p1'),(2,'p2'),
      (3,'p3'),(4,'p4')
      
      ;with cte as (
      SELECT [name] ,[count],ts 
      FROM [current_table]  t
      UNPIVOT ([count] FOR [name] IN ([p1],[p2],[p3],[p4])) u)
      select b.id,a.count,a.ts from  cte a  join [definition] b on a.name=b.name
      /*
      id          count       ts
      ----------- ----------- ----------
      1           5           2018-12-06
      2           88          2018-11-01
      2           18          2018-10-18
      3           32          2018-10-27
      4           6           2018-10-14
      */
      
      
      ------dynamic-------------
      DECLARE @ColNames varchar(1000);
      SET @ColNames = '';
      SELECT @ColNames =stuff((
          SELECT DISTINCT ',' + QUOTENAME(COLUMN_NAME)
          FROM INFORMATION_SCHEMA.COLUMNS p2
          WHERE TABLE_NAME = 'current_table'
            AND COLUMN_NAME like 'p%'
          FOR XML PATH(''), TYPE).value('.', 'varchar(max)')
                  ,1,1,'')
      DECLARE @CMD nvarchar(2000);
      SET @CMD = ';with cte as (
      SELECT [name] ,[count],ts 
      FROM [current_table]  t
      UNPIVOT ([count] FOR [name] IN ('+@ColNames+')) u)
      select b.id,a.count,a.ts from  cte a  join [definition] b on a.name=b.name'
      PRINT @CMD
      execute sp_executesql @CMD
      /*
      ;with cte as (
      SELECT [name] ,[count],ts 
      FROM [current_table]  t
      UNPIVOT ([count] FOR [name] IN ([p1],[p2],[p3],[p4])) u)
      select b.id,a.count,a.ts from  cte a  join [definition] b on a.name=b.name
      id          count       ts
      ----------- ----------- ----------
      1           5           2018-12-06
      2           88          2018-11-01
      2           18          2018-10-18
      3           32          2018-10-27
      4           6           2018-10-14
      */
      

      希望对你有帮助。

      最好的问候,

      雷切尔

      【讨论】:

        猜你喜欢
        • 2022-07-29
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-03
        • 2013-07-22
        • 1970-01-01
        相关资源
        最近更新 更多