获取详细信息的SQL查询

时间:2014-08-08 14:43:48

标签: sql-server-2008 pivot

我们有一个包含机器详细信息的数据库,如ID,主机名,IP地址,操作系统等......

ID  IP Address      Hostname     Protocol    NetMask
1   10.216.16.47    Test123         DNS     255.255.255.0
1   10.216.16.48    Test123         DNS     255.255.255.0
54  10.216.68.85    Test73711340    DNS     255.255.255.0
71  10.216.63.101   Test737101230   DNS     255.255.255.0
94  10.216.34.153   Test10000182    DNS     255.255.255.0

我需要编写一个查询,它将找到一台具有两个IP地址的计算机,并为每个IP为输出提供一个单独的列。

预期产出:

ID  IP Address     IP Address 2     Hostname      Protocol      NetMask
1   10.216.16.47   10.216.16.48    Test123         DNS      255.255.255.0
54  10.216.68.85    Null           Test73711340    DNS      255.255.255.0
71  10.216.63.101   Null           Test737101230   DNS      255.255.255.0
94  10.216.34.153   Null           Test10000182    DNS      255.255.255.0

任何建议?

1 个答案:

答案 0 :(得分:0)

为了得到这个结果,你首先需要使用像row_number()这样的窗口函数来为ID中的每一行分配一个不同的值 - 这意味着任何多行ID 1}}你将在该ID中创建一个唯一的序列。

我建议使用类似于:

的row_number
select id,
 IPAddress,
  Hostname,
  Protocol,
  NetMask,
  col = 'IPAddress'+
          cast(row_number() over(partition by id order by IPAddress) as varchar(1))
from yourtable;

SQL Fiddle with Demo。此查询创建一个具有序列的新计算列,然后将术语“IPAddress”连接到它的前面,您会注意到ID=1有两个值IPAddress1IPAddress2 - 这些新值将用作新列。

| ID |     IPADDRESS |      HOSTNAME | PROTOCOL |       NETMASK |        COL |
|----|---------------|---------------|----------|---------------|------------|
|  1 |  10.216.16.47 |       Test123 |      DNS | 255.255.255.0 | IPAddress1 |
|  1 |  10.216.16.48 |       Test123 |      DNS | 255.255.255.0 | IPAddress2 |

然后,如果要将其转换为列,可以使用PIVOT函数:

select id,
  IPAddress1,
  IPAddress2,
  Hostname,
  Protocol,
  NetMask
from
(
  select id,
    IPAddress,
    Hostname,
    Protocol,
    NetMask,
    col = 'IPAddress'+
            cast(row_number() over(partition by id order by IPAddress) as varchar(1))
  from yourtable
) d
pivot
(
  max(IPAddress)
  for col in (IPAddress1, IPAddress2)
) p;

SQL Fiddle with Demo

或者您也可以使用带有CASE表达式的聚合函数来获取结果:

select id,
  IPAddress1 = max(case when rn = 1 then IPAddress end),
  IPAddress2 = max(case when rn = 2 then IPAddress end),
  Hostname,
  Protocol,
  Netmask
from
(
  select id,
    IPAddress,
    Hostname,
    Protocol,
    NetMask,
    rn = row_number() over(partition by id order by IPAddress)
  from yourtable
) d
group by id, hostname, protocol, netmask;

SQL Fiddle with Demo。 pivot和case版本都会得到以下结果:

| ID |    IPADDRESS1 |   IPADDRESS2 |      HOSTNAME | PROTOCOL |       NETMASK |
|----|---------------|--------------|---------------|----------|---------------|
|  1 |  10.216.16.47 | 10.216.16.48 |       Test123 |      DNS | 255.255.255.0 |
| 54 |  10.216.68.85 |       (null) |  Test73711340 |      DNS | 255.255.255.0 |
| 71 | 10.216.63.101 |       (null) | Test737101230 |      DNS | 255.255.255.0 |
| 94 | 10.216.34.153 |       (null) |  Test10000182 |      DNS | 255.255.255.0 |