Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

SQL - Транспониране на колона в ред

Има 100 пивот примера на SO, така че исках да покажа начин, по който можете да направите това, който не е толкова добър като пивота, но работи за вашия екземпляр. Може да не отговаря на целия ви набор от данни и се основава само на вашите примерни данни.

Трябва да се отбележи, че вашите тестови данни не предоставят резултатите, които твърдите, че дават. Вероятно е просто правописна грешка във вложката.

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

ИЗПОЛЗВАНЕ НА DYNAMIC PIVOT

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Най-бързият начин за актуализиране на 120 милиона записа

  2. Как да изтрия големи данни от таблица в SQL без дневник?

  3. Връщане на последния въведен ID без използване на втора заявка

  4. Ако актуализирам изглед, оригиналните ми таблици ще бъдат ли актуализирани

  5. Как да актуализирате първичен ключ