Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL-将列转换为行_Sql_Sql Server 2008_Tsql_Pivot - Fatal编程技术网

SQL-将列转换为行

SQL-将列转换为行,sql,sql-server-2008,tsql,pivot,Sql,Sql Server 2008,Tsql,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', '29

好的,我已经搜索过了,但是找不到像我在这里尝试做的那样具体的东西。我有两个不同的表,我需要从中获取信息。这是一个示例模式-类似于我的工作:

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');
insert into Nodes (Caption, IP_Address, NodeID)
values ('prod-srvr', '10.0.2.1', '29056');
insert into Nodes (Caption, IP_Address, NodeID)
values ('test-srvr', '10.1.1.1', '29087');

create table Volumes(
  Caption varchar(max),
  NodeID varchar(max)
);

insert into Volumes (NodeID, Caption)
values ('29023', '/');
insert into Volumes (NodeID, Caption)
values ('29023', '/boot');
insert into Volumes (NodeID, Caption)
values ('29023', '/dev/shm');
insert into Volumes (NodeID, Caption)
values ('29023', '/home');
insert into Volumes (NodeID, Caption)
values ('29056', '/');
insert into Volumes (NodeID, Caption)
values ('29056', '/var');
insert into Volumes (NodeID, Caption)
values ('29056', '/opt');
insert into Volumes (NodeID, Caption)
values ('29087', '/tmp');
我正在尝试编写一个查询(带有where子句…在最终版本中将有多个a过滤器),该查询将返回Node.Caption、IP_地址和每个关联的Volumes.Caption(基于NodeID)。卷中的条目数。每个节点ID的标题是动态的,从1到大约60个不等。我所知道的写作方法是:

select Nodes.Caption, Nodes.IP_Address, Volumes.Caption as Volume
from Nodes with (nolock)
inner join Volumes
on Nodes.NodeID=Volumes.NodeID
where IP_Address like '10.0%'
返回以下内容:

Caption   | IP_Address | Volume
---------------------------------
dev-srvr  | 10.0.0.1   | /
dev-srvr  | 10.0.0.1   | /boot
dev-srvr  | 10.0.0.1   | /dev/shm
dev-srvr  | 10.0.0.1   | /home
prod-srvr | 10.0.0.1   | /var
prod-srvr | 10.0.0.1   | /opt
但我需要的是每个节点一行ID,显示Node.Caption、IP_地址和所有匹配的卷(如果可能的话)。这样(最后的列名并不重要……可以是任何内容):


上面有100个pivot示例,所以我想展示一种方法,可以实现这一点,它不如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');


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

是的,对不起,我没有把我的东西复制到正确的位置。非常感谢你!你想出来的正是我绞尽脑汁想弄明白的。问题…有没有办法让它充满活力?例如,我不知道服务器上是否会有4个卷,15、65等?SQL是否可以根据需要添加任意多个“max(Volume#)作为Volume#”和“case when RN=#那么Volume end作为Volume#”?或者只添加我认为我们需要的列(比如5到100列)会更容易吗?@fishbot您需要在不知道将有多少列的任何时候使用带有枢轴的动态sql。在本例中,您还创建了列名,而不是从行值显式使用列名。第二段代码展示了如何使用row_number实现这一点。
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