如何在具有条件的表中转动行?

时间:2013-11-19 11:48:02

标签: sql sql-server pivot

我想用SQL脚本在数据库中透视数据。这就是表格中的样子。

id  name        state   cpu_usage   memory_usage    datetime
1   machine-2   Running 50.6693     5060099372      2013-11-18 17:00:22.550
2   machine-3   Running 19.8329     14951967776     2013-11-18 17:00:22.550
3   machine-4   Running 24.2103     3309923047      2013-11-18 17:00:22.550
4   machine-2   Running 97.2774     2867303718      2013-11-18 17:01:22.550
5   machine-3   Running 66.2991     11048043786     2013-11-18 17:01:22.550
6   machine-5   Running 26.6446     13362336682     2013-11-18 17:01:22.550
7   machine-2   Running 39.5881     6969468931      2013-11-18 17:02:22.550
8   machine-3   Running 99.0000     9340168327      2013-11-18 17:02:22.550
9   machine-4   Running 85.0968     16154409604     2013-11-18 17:02:22.550

这就是我希望结果与CPU使用情况相似的方式。

Date                        machine-2   machine-3   machine-4   machine-5
2013-11-18 17:00:22.550     50.6693     19.8329     24.2103     null
2013-11-18 17:01:22.550     97.2774     66.2991     null        26.6446
2013-11-18 17:02:22.550     39.5881     99.0000     85.0968     null

如何使用SQL执行此操作?

1 个答案:

答案 0 :(得分:3)

您可以通过几种不同的方式获得结果。

您可以使用条件逻辑应用带有CASE表达式的聚合函数来创建新列:

select datetime,
  max(case when name = 'machine-2' then cpu_usage end) machine2,
  max(case when name = 'machine-3' then cpu_usage end) machine3,
  max(case when name = 'machine-4' then cpu_usage end) machine4,
  max(case when name = 'machine-5' then cpu_usage end) machine5
from yourtable
group by datetime;

请参阅SQL Fiddle with Demo

或者您可以应用PIVOT功能,将name值转换为列:

select datetime,
  [machine-2], [machine-3], 
  [machine-4], [machine-5]
from
(
  select datetime, name, cpu_usage
  from yourtable
) d
pivot
(
  max(cpu_usage)
  for name in ([machine-2], [machine-3], [machine-4], [machine-5])
) piv;

请参阅SQL Fiddle with Demo

如果name列的值有限,上述两个版本将适用于您,但如果没有,那么您将需要查看使用动态SQL:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(name) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT datetime,' + @cols + ' 
            from 
            (
              select datetime, name, cpu_usage
              from yourtable
            ) x
            pivot 
            (
                max(cpu_usage)
                for name in (' + @cols + ')
            ) p '

execute sp_executesql @query;

SQL Fiddle with Demo。所有版本都给出了结果:

|                        DATETIME | MACHINE-2 | MACHINE-3 | MACHINE-4 | MACHINE-5 |
|---------------------------------|-----------|-----------|-----------|-----------|
| November, 18 2013 17:00:22+0000 |   50.6693 |   19.8329 |   24.2103 |    (null) |
| November, 18 2013 17:01:22+0000 |   97.2774 |   66.2991 |    (null) |   26.6446 |
| November, 18 2013 17:02:22+0000 |   39.5881 |        99 |   85.0968 |    (null) |