【问题标题】:Unpivot using Dynamic query使用动态查询反透视
【发布时间】:2020-05-09 20:03:23
【问题描述】:

我正在编写一个查询,根据需要根据表的第一列和选定的行来取消透视表。我在动态查询中遇到了一个问题。实际表有 77 个不同数据类型的列,我试图将其转换为varchar,并且这些值将始终属于表的特定行。 示例:

CREATE TABLE EXAMPLE (ROWDATA INT, CHARDATA VARCHAR(MAX), BIGINTCOLUMN BIGINT)
INSERT INTO EXAMPLE (ROWDATA INT, CHARDATA VARCHAR(MAX), BIGINTCOLUMN BIGINT)
VALUES (1, AB, 15698), (2, BD, 23467), (3, ABC, 42378)
  • 现在我想在不放置列的情况下进行反透视操作,以便我可以将其用于多种用途,并且应该只有 2 列,一列是包含值的 ColumnName
  • “CHARDATA,BIGINTCOLUMN”其他 ColumnValue 包含诸如“BD,23467”或“ABC,42378”之类的值'

代码:

create table #ColumnName (Countno int identity(1,1), Column_Name varchar(max))
insert into #ColumnName (Column_Name) select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'EXAMPLE'
Create table #Converttype (Countno int identity(1,1), Converttype varchar(max)) 
insert into #Converttype (Converttype) select case when DATA_TYPE <> 'varchar' then 'Cast(' + COLUMN_NAME + ' as varchar) as '+ COLUMN_NAME else COLUMN_NAME end from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'EXAMPLE'

declare @CreateTable varchar(max) =(select Column_Name from #ColumnName where Countno = 1)
declare @Converttype varchar(max) = (select Converttype from #Converttype where Countno = 1)    
declare @ColumnName varchar(max) = (select Column_Name from #ColumnName where Countno = 2)
declare @Iteration int = (select Count(COLUMN_NAME) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'EXAMPLE')
declare @count int = 2

while @Count <= @Iteration
begin
    --print @Count

    set @CreateTable = @CreateTable+' varchar(max)' + ',' + (select Column_Name from #ColumnName where Countno = @count) 
    set @Converttype = @Converttype + ',' + (select Converttype from #Converttype where Countno = @count)

    set @count = @count + 1
    set @ColumnName = @ColumnName + ',' + isnull((select Column_Name from #ColumnName where Countno = @count),'') 
end

declare @Unpivot nvarchar(max) = ' 
create table #temp (' + @CreateTable + ' varchar(max))
insert into #temp (ROWDATA,' + @ColumnName + ')
select ' + @Converttype + '  from EXAMPLE where ROWDATA = 2
select * from #temp
unpivot
(
    ColumnValue
    for ColumnName in (' + @ColumnName + ')
) AS Tablecheck'

Exec(@Unpivot)
  • 调试后我发现@Unpivot 在我使用 print @Unpivot 时没有特别工作,它没有显示从select * from #temp) as Tablecheck 的消息

【问题讨论】:

    标签: sql-server unpivot dynamicquery


    【解决方案1】:

    @ColumnName 末尾的多余逗号只是一个小问题,否则您的脚本可以正常工作。

    CREATE TABLE #ColumnName
    (Countno     INT IDENTITY(1, 1), 
     Column_Name VARCHAR(MAX)
    );
    INSERT INTO #ColumnName(Column_Name)
           SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'EXAMPLE';
    
    CREATE TABLE #Converttype
    (Countno     INT IDENTITY(1, 1), 
     Converttype VARCHAR(MAX)
    ); 
    INSERT INTO #Converttype(Converttype)
           SELECT CASE
                      WHEN DATA_TYPE <> 'varchar'
                      THEN 'Cast(' + COLUMN_NAME + ' as varchar (max)) as ' + COLUMN_NAME
                      ELSE COLUMN_NAME
                  END
           FROM INFORMATION_SCHEMA.COLUMNS
           WHERE TABLE_NAME = 'EXAMPLE';
    
    
    
    DECLARE @CreateTable VARCHAR(MAX)=
    (
        SELECT Column_Name FROM #ColumnName WHERE Countno = 1
    );
    DECLARE @Converttype VARCHAR(MAX)=
    (
        SELECT Converttype FROM #Converttype WHERE Countno = 1
    );
    DECLARE @ColumnName VARCHAR(MAX)=
    (
        SELECT Column_Name FROM #ColumnName WHERE Countno = 2
    );
    DECLARE @Iteration INT=
    (
        SELECT COUNT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'EXAMPLE'
    );
    
    SELECT @Iteration
    
    DECLARE @count INT= 2;
    WHILE @Count <= @Iteration
        BEGIN
            print @Count
    
            SET @CreateTable = @CreateTable + ' varchar(max)' + ',' +
            (
                SELECT Column_Name FROM #ColumnName WHERE Countno = @count
            );
            SET @Converttype = @Converttype + ',' +
            (
                SELECT Converttype FROM #Converttype WHERE Countno = @count
            );
            SET @count = @count + 1;
            SET @ColumnName = @ColumnName + ',' + ISNULL(
            (
                SELECT Column_Name FROM #ColumnName WHERE Countno = @count
            ), '');
        END;
    
    
    
    DECLARE @Unpivot NVARCHAR(MAX)= ' 
    create table #temp (' + @CreateTable + ' varchar(max))
    insert into #temp (ROWDATA,' + SUBSTRING(@ColumnName, 1, LEN(@COLUMNNAME) - 1) + ')
    select ' + @Converttype + '  from EXAMPLE where ROWDATA >= 2
    select * from #temp
    unpivot
    (
        ColumnValue
        for ColumnName in (' + SUBSTRING(@ColumnName, 1, LEN(@COLUMNNAME) - 1) + ')
    ) AS Tablecheck';
    
    print (@unpivot)
    EXEC (@Unpivot);
    

    请看 dbfiddle here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-28
      • 2015-03-21
      • 1970-01-01
      • 2015-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多