sql >> データベース >  >> RDS >> Sqlserver

SQL - 列を行に転置

    SO には 100 のピボットの例があるので、これを行う方法を示したいと思いました。これはピボットほど良くはありませんが、インスタンスでは機能します。データセット全体に適合しない可能性があり、サンプル データのみに基づいています。

    注目すべきは、あなたのテストデータは、あなたが主張する結果を提供していないということです。おそらく挿入のタイプミスです。

    create table #Nodes(
      Caption varchar(max),
      IP_Address varchar(max),
      NodeID varchar(max)
    );
    
    insert into #Nodes (Caption, IP_Address, NodeID)
    values 
    ('dev-srvr', '10.0.0.1', '29023'),
    ('prod-srvr', '10.0.2.1', '29056'),
    ('test-srvr', '10.1.1.1', '29087');
    
    create table #Volumes(
      Caption varchar(max),
      NodeID varchar(max)
    );
    
    insert into #Volumes (NodeID, Caption)
    values 
     ('29023', '/'),
     ('29023', '/boot'),
     ('29023', '/dev/shm'),
     ('29023', '/home'),
     ('29056', '/'),
     ('29056', '/var'),
     ('29056', '/opt'),
     ('29087', '/tmp');
    
    
    select 
        n.Caption, 
        n.IP_Address, 
        v.Caption as Volume
    from #Nodes n
    inner join #Volumes v
    on n.NodeID=v.NodeID
    where IP_Address like '10.0%'
    
    ;with cte as(
    select 
        n.Caption, 
        n.IP_Address, 
        v.Caption as Volume,
        ROW_NUMBER() over (partition by n.caption, IP_Address order by n.caption) as RN
    from #Nodes n
    inner join #Volumes v
    on n.NodeID=v.NodeID
    where IP_Address like '10.0%')
    
    select
        x.caption,
        x.IP_Address,
        max(Volume1) as Volume1,
        max(Volume2) as Volume2,
        max(Volume3) as Volume3,
        max(Volume4) as Volume4
    from(
        select
            Caption,
            IP_Address,
            case when RN = 1 then Volume end as Volume1,
            case when RN = 2 then Volume end as Volume2,
            case when RN = 3 then Volume end as Volume3,
            case when RN = 4 then Volume end as Volume4
        from cte) x
    group by x.Caption, x.IP_Address
    
    
    drop table #Nodes
    drop table #Volumes
    

    動的ピボットの使用

    create table #Nodes(
      Caption varchar(max),
      IP_Address varchar(max),
      NodeID varchar(max)
    );
    
    insert into #Nodes (Caption, IP_Address, NodeID)
    values 
    ('dev-srvr', '10.0.0.1', '29023'),
    ('prod-srvr', '10.0.2.1', '29056'),
    ('test-srvr', '10.1.1.1', '29087');
    
    create table #Volumes(
      Caption varchar(max),
      NodeID varchar(max)
    );
    
    insert into #Volumes (NodeID, Caption)
    values 
     ('29023', '/'),
     ('29023', '/boot'),
     ('29023', '/dev/shm'),
     ('29023', '/home'),
     ('29056', '/'),
     ('29056', '/var'),
     ('29056', '/opt'),
     ('29087', '/tmp');
    
    
    
    DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
    DECLARE @ColumnName AS NVARCHAR(MAX)
    
    
    select 
        n.Caption, 
        n.IP_Address, 
        v.Caption as Volume,
        'Volume' + cast(ROW_NUMBER() over (partition by n.caption, IP_Address order by n.caption) as varchar(16)) as Cname
        --ROW_NUMBER() over (partition by n.caption, IP_Address order by n.caption) as RN
    into #staging
    from #Nodes n
    inner join #Volumes v
    on n.NodeID=v.NodeID
    where IP_Address like '10.0%'
    
    
    
    
    --Get distinct values of the PIVOT Column 
    SELECT @ColumnName= ISNULL(@ColumnName + ',','') 
           + QUOTENAME(Cname)
    FROM (SELECT DISTINCT Cname FROM #staging) AS Cname
    
    --Prepare the PIVOT query using the dynamic 
    SET @DynamicPivotQuery = 
      N'SELECT Caption, IP_Address, ' + @ColumnName + '
        FROM #staging
        PIVOT(MAX(Volume) 
              FOR Cname IN (' + @ColumnName + ')) AS PVTTable'
    --Execute the Dynamic Pivot Query
    EXEC sp_executesql @DynamicPivotQuery
    
    
    
    drop table #Nodes
    drop table #Volumes
    drop table #staging
    



    1. MariaDBでのDIVのしくみ

    2. MySQLに`connectby`の代替手段はありますか?

    3. クエリ文字列値を使用してデータベースからデータをクエリする方法

    4. Django DatabaseError後に再接続する方法:クエリタイムアウト