将SQL Row转置为具有多个分组数据的列

时间:2017-11-22 14:16:11

标签: sql oracle12c

我在oracle sql 12c中转动/转置数据时遇到问题,

我有一个像这样的源表: enter image description here

我的目的是像这样转置到目标表: enter image description here

我怎样才能做到这一点?我一直在选择要在目标表中写入的主机名类别的特定值。

请咨询,

谢谢你, galih

2 个答案:

答案 0 :(得分:0)

我解决了问题,并在SQL Server中执行查询。

创建表格并插入样本数据:

CREATE TABLE [dbo].[tmpTbl](
        [date] [datetime] NULL,
        [time] [datetime] NULL,
        [hostname] [nvarchar](30) NULL,
        [type] [nvarchar](30) NULL,
        [category] [nvarchar](30) NULL,
        [target] [nvarchar](30) NULL,
        [value] [decimal](18, 2) NULL
    )

insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'gate1', 'FIREWALL', 'DISCARD', 'gate1', 0.02)
insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'gate1', 'FIREWALL', 'ERROR', 'gate1', 0)
insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'gate1', 'FIREWALL', 'REACHABILITY', 'gate1', 100)
insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'gate1', 'FIREWALL', 'THROUGHTPUT', 'gate1', 172527000)
insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'gate2', 'FIREWALL', 'DISCARD', 'gate2', 0)
insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'gate2', 'FIREWALL', 'ERROR', 'gate2', 0)
insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'gate2', 'FIREWALL', 'REACHABILITY', 'gate2', 100)
insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'gate2', 'FIREWALL', 'THROUGHTPUT', 'gate2', 121986000)

insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'webmail1', 'LOAD BALANCER', 'CONNECTION', 'webmail1', 10395)
insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'webmail1', 'LOAD BALANCER', 'CPU_utilization', 'webmail1', 28)
insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'webmail1', 'LOAD BALANCER', 'DISCARD', 'webmail1', 1.2)
insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'webmail1', 'LOAD BALANCER', 'ERROR', 'webmail1', 0)
insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'webmail1', 'LOAD BALANCER', 'REACHABILITY', 'webmail1', 100)

insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'webmail2', 'LOAD BALANCER', 'Status', 'webmail2', 100)
insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'webmail2', 'LOAD BALANCER', 'THROUGHTPUT', 'webmail2', 56680700)
insert into tmpTbl values ('01 Oct 2017', '0:00:00', 'webmail2', 'LOAD BALANCER', 'CONNECTION', 'webmail2', 0)

Dinamic SQL PIVOT查询:

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

    SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.category) 
            FROM tmpTbl c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

    SET @SQL = 'SELECT Year([date]) AS [YEAR], Month([date]) AS [MONTH], CONVERT(VARCHAR(10), [date], 103) AS DATEX, 
            DATEPART(HOUR, [date]) AS [HOURX], [type] AS DEVICE_TYPE, [hostname] AS DEVICE_NAME, ' + @cols + ' from 
                (
                select [date]
                    , [type]
                    , [hostname]
                    , value
                    , category
                from tmpTbl
                ) T
                 PIVOT 
                    (
                        MAX(value)
                        for category in (' + @cols + ')
                    ) pv '

    Execute(@SQL)

    drop table tmpTbl

结果:

enter image description here

答案 1 :(得分:0)

这是一个可能与Oracle一起使用的数据透视逻辑。我已经从关键字更改了一些列名以避免问题。

SELECT EXTRACT(YEAR FROM DATEX) YEAR,
  EXTRACT(MONTH FROM DATEX) MONTH,
  DATEX,
  TIMEX,
  TYPE DEVICE_TYPE,
  HOSTNAME DEVICE_NAME,
  SUM(CASE WHEN category = 'MEMORY' THEN valued ELSE NULL END) MEMORY,
  SUM(CASE WHEN category = 'DISCARD' THEN valued ELSE NULL END) DISCARDED,
  SUM(CASE WHEN category = 'ERROR' THEN valued ELSE NULL END) ERROR,
  SUM(CASE WHEN category = 'REACHBILITY' THEN valued ELSE NULL END) REACHBILITY,
  SUM(CASE WHEN category = 'STATUS' THEN valued ELSE NULL END) STATUSES,
  SUM(CASE WHEN category = 'THROUGHPUT' THEN valued ELSE NULL END) THROUGHPUT,
  SUM(CASE WHEN category = 'CONNECTION' THEN valued ELSE NULL END) CONNECTIONS
FROM tmpTbl
GROUP BY DATEX, TIMEX, TYPE, HOSTNAME

希望这会有所帮助。