好的,我已经搜索过,但找不到任何具体的内容,就像我想在这里做的那样。我有两个不同的表,我需要信息。这是一个示例模式 - 类似于我的工作方式:
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子句...将在最终版本上有多个过滤器),它将返回Node.Caption,IP_Address和每个与相关的Volumes.Caption(基于NodeID) 。 Volumes.Caption中每个NodeID的条目数是动态的,从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
但我需要的是每个NodeID的单个ROW,如果可能的话,显示Node.Caption,IP_Address和所有匹配的卷。像这样(最后的列名不重要......可以是任何东西):
Caption | IP_Address | Volume1 | Volume2 | Volume3 | Volume 4
----------------------------------------------------------------
dev-srvr | 10.0.0.1 | / | /boot | /dev/shm | /home
prod-srvr | 10.0.0.1 | /var | /opt
答案 0 :(得分:1)
在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
使用动态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