代码之家  ›  专栏  ›  技术社区  ›  JeffO

SQL Server-使用UNPIVOT包含NULL

  •  17
  • JeffO  · 技术社区  · 16 年前

    UNPIVOT NULL query ISNULL

    Select ID, theValue, column_name
    From 
    (select ID,
      ISNULL(CAST([TheColumnToCompare]  AS VarChar(1000)), '') as TheColumnToCompare
      from MyView
      where The_Date = '04/30/2009'
    ) MA
    UNPIVOT
       (theValue FOR column_name IN 
       ([TheColumnToCompare])
    ) AS unpvt
    

    7 回复  |  直到 5 年前
        1
  •  24
  •   Michel de Ruiter    5 年前

    要保留空值,请使用交叉联接。。。案例:

    select a.ID, b.column_name
    , column_value = 
        case b.column_name
          when 'col1' then a.col1
          when 'col2' then a.col2
          when 'col3' then a.col3
          when 'col4' then a.col4
        end
    from (
      select ID, col1, col2, col3, col4 
      from table1
      ) a
    cross join (
      select 'col1' union all
      select 'col2' union all
      select 'col3' union all
      select 'col4'
      ) b (column_name)
    

    select ID, column_name, column_value
    From (
      select ID, col1, col2, col3, col4
      from table1
      ) a
    unpivot (
      column_value FOR column_name IN (
        col1, col2, col3, col4)
      ) b
    

    您可能需要为100列编写脚本。

        2
  •  19
  •   Cade Roux    16 年前

    UNPIVOT ISNULL()

    PIVOT NULL 0.0

        3
  •  9
  •   Tom Blodget    6 年前

    我遇到了同样的问题。使用 CROSS APPLY (SQL Server 2005及更高版本)而不是 Unpivot An Alternative (Better?) Method to UNPIVOT Unpivot

    create table #Orders (OrderDate datetime, product nvarchar(100), ItemsCount float, GrossAmount float, employee nvarchar(100))
    
     insert into #Orders
     select getutcdate(),'Windows',10,10.32,'Me'
     union 
     select getutcdate(),'Office',31,21.23,'you'
     union 
     select getutcdate(),'Office',31,55.45,'me'
     union  
     select getutcdate(),'Windows',10,null,'You'
    
    SELECT OrderDate, product,employee,Measure,MeasureType
     from #Orders orders
     CROSS APPLY (
        VALUES ('ItemsCount',ItemsCount),('GrossAmount',GrossAmount)
        ) 
        x(MeasureType, Measure) 
    
    
    SELECT OrderDate, product,employee,Measure,MeasureType
    from #Orders orders
    UNPIVOT
       (Measure FOR MeasureType IN 
          (ItemsCount,GrossAmount)
    )AS unpvt;
    
    
     drop table #Orders
    
        4
  •  3
  •   chue x    10 年前

    ...
    cross join 
    (values('col1'), ('col2'), ('col3'), ('col4')) column_names(column_name)
    
        5
  •  2
  •   Beej    12 年前

    -- test data
    CREATE TABLE _t1(name varchar(20),object_id varchar(20),principal_id varchar(20),schema_id varchar(20),parent_object_id varchar(20),type varchar(20),type_desc varchar(20),create_date varchar(20),modify_date varchar(20),is_ms_shipped varchar(20),is_published varchar(20),is_schema_published varchar(20))
    INSERT INTO _t1 SELECT 'blah1', 3, NULL, 4, 0, 'blah2', 'blah3', '20100402 16:59:23.267', NULL, 1, 0, 0 
    
    -- example
    select c.COLUMN_NAME, Value
    from INFORMATION_SCHEMA.COLUMNS c
    left join (
      select * from _t1
    ) q1
    unpivot (Value for COLUMN_NAME in (name,object_id,principal_id,schema_id,parent_object_id,type,type_desc,create_date,modify_date,is_ms_shipped,is_published,is_schema_published)
    ) t on t.COLUMN_NAME = c.COLUMN_NAME
    where c.TABLE_NAME = '_t1'
    </pre>
    

    +----------------------+-----------------------+
    |    COLUMN_NAME       |        Value          |
    +----------------------+-----------------------+
    | name                 | blah1                 |
    | object_id            | 3                     |
    | principal_id         | NULL                  | <======
    | schema_id            | 4                     |
    | parent_object_id     | 0                     |
    | type                 | blah2                 |
    | type_desc            | blah3                 |
    | create_date          | 20100402 16:59:23.26  |
    | modify_date          | NULL                  | <======
    | is_ms_shipped        | 1                     |
    | is_published         | 0                     |
    | is_schema_published  | 0                     |
    +----------------------+-----------------------+
        
        6
  •  1
  •   Charlie    13 年前

    使用动态SQL和COALESCE,我解决了如下问题:

    DECLARE @SQL NVARCHAR(MAX)
    DECLARE @cols NVARCHAR(MAX)
    DECLARE @dataCols NVARCHAR(MAX)
    
    SELECT 
        @dataCols = COALESCE(@dataCols + ', ' + 'ISNULL(' + Name + ',0) ' + Name , 'ISNULL(' + Name + ',0) ' + Name )
    FROM Metric WITH (NOLOCK)
    ORDER BY ID
    
    SELECT 
        @cols = COALESCE(@cols + ', ' + Name , Name )
    FROM Metric WITH (NOLOCK)
    ORDER BY ID
    
    SET @SQL = 'SELECT ArchiveID, MetricDate, BoxID, GroupID, ID MetricID, MetricName, Value
                FROM 
                   (SELECT ArchiveID, [Date] MetricDate, BoxID, GroupID,  ' + @dataCols + '
                    FROM MetricData WITH (NOLOCK)
                    INNER JOIN Archive WITH (NOLOCK)
                        ON ArchiveID = ID
                    WHERE BoxID = ' + CONVERT(VARCHAR(40), @BoxID) + '
                    AND GroupID = ' + CONVERT(VARCHAR(40), @GroupID) + ') p
                UNPIVOT
                   (Value FOR MetricName IN 
                      (' + @cols + ')
                )AS unpvt
                INNER JOIN Metric WITH (NOLOCK)
                    ON MetricName  = Name
                ORDER BY MetricID, MetricDate'
    
    EXECUTE( @SQL )
    
        7
  •  -1
  •   John Kelly    10 年前

    ISNULL是答案的一半。使用NULLIF将其转换回NULL。例如。

    DECLARE @temp TABLE(
        Foo varchar(50),
        Bar varchar(50) NULL
        );
    
    INSERT INTO @temp( Foo,Bar )VALUES( 'licious',NULL );
    
    SELECT * FROM @temp;
    
    SELECT 
        Col,
        NULLIF( Val,'0Null' ) AS Val 
    FROM(
        SELECT
            Foo,
            ISNULL( Bar,'0Null' ) AS Bar
        FROM
            @temp
        ) AS t
    UNPIVOT(
        Val FOR Col IN(
            Foo,
            Bar 
            )
        ) up;