根据其他列按月显示记录

时间:2015-08-12 18:27:32

标签: sql-server sql-server-2008

以下是我的表中包含的数据。我已经分享了查询以及我需要的结果。 根据IPAddress列,我必须按月计算数据并将其显示为特定月份的IP地址和外部IP地址。

这是DDL和样本数据:

SELECT *
FROM (
select DEPTNO, datename(month,HIREDATE) [month],COUNT(IPAddress) Amount from [#IPAddress] where IPAddress between 1 and 10 group by DEPTNO,datename(month,HIREDATE)
) as s
PIVOT
(
    SUM(Amount) FOR [month] IN (December,February,January,November,September)
)AS pvt

SELECT *
FROM (
select DEPTNO, datename(month,HIREDATE) [month],COUNT(IPAddress) Amount from [#IPAddress] where IPAddress between 11 and 20 group by DEPTNO,datename(month,HIREDATE)
) as s
PIVOT
(
    SUM(Amount) FOR [month] IN (December,February,January,November,September)
)AS pvt

我的要求是:

select 10 DeptNo,null DecemberInIPAddress,null DecemberOutIPAddress,null FebruaryInIPAddress,null FebruaryOutIPAddress,1 JanuaryInIPAddress,null JanuaryOutIPAddress,
null NovemberInIPAddress,1 NovemberOutIPAddress, null SeptemberInIPAddress,null SeptemberOutIPAddress 
union
select 20 DeptNo,1 DecemberInIPAddress,2 DecemberOutIPAddress,null FebruaryInIPAddress,null FebruaryOutIPAddress,null JanuaryInIPAddress,1 JanuaryOutIPAddress,
null NovemberInIPAddress,null NovemberOutIPAddress, null SeptemberInIPAddress,null SeptemberOutIPAddress 
union
    select 30 DeptNo,1 DecemberInIPAddress,null DecemberOutIPAddress,1 FebruaryInIPAddress,1 FebruaryOutIPAddress,null JanuaryInIPAddress,null JanuaryOutIPAddress,
    null NovemberInIPAddress,null NovemberOutIPAddress, null SeptemberInIPAddress,2 SeptemberOutIPAddress 

执行上述查询后,我得到2个结果集。

但我希望数据类似于 -

{{1}}

给出一个结果集的最终查询,我想要那样的结果。

1 个答案:

答案 0 :(得分:0)

要获得所需的输出,您可以轻松使用两个查询,并在DeptNo上进行加入,如下所示:

;WITH in_IPaddress
AS (
    SELECT *
    FROM (
        SELECT DEPTNO
            ,datename(month, HIREDATE) [month]
            ,IPAddress
        FROM [#IPAddress]
        WHERE IPaddress BETWEEN 1 AND 10
        ) AS s
    PIVOT(COUNT(IPAddress) FOR [month] IN (December,February,January,November,September)
    ) AS pvt
    ),
out_IPAddress
AS (
    SELECT *
    FROM (
        SELECT DEPTNO
            ,datename(month, HIREDATE) [month]
            ,IPAddress
        FROM [#IPAddress]
        WHERE IPaddress BETWEEN 11 AND 20
        ) AS s
    PIVOT(COUNT(IPAddress) FOR [month] IN (December,February,January,November,September)
    ) AS pvt
    )
SELECT 
      i.deptno
    ,i.December AS DecemberInIp
    ,o.December AS DecemberOutIp
    ,i.February AS FebruaryInIp
    ,o.February AS FebruaryOutIp
    ,i.January AS JanuaryInIp
    ,o.January AS JanuaryOutIp
    ,i.November AS NovemberInIp
    ,o.November AS NovemberOutIp
    ,i.September AS SeptemberInIp
    ,o.September AS SeptemberOutIp
FROM in_IPAddress i
LEFT JOIN out_IPAddress o ON i.deptNO = o.DeptNo;

Code Demo

另一方面,我也调整了您的数据透视查询:删除了group by,而不是sum上的IPAddress,而是使用了count。此外,您可能会注意到输出结果返回0而不是空值,可以使用“大小写”来轻松替换。外部查询中的语句。

<强>更新

由于您的列名不是静态的,因此您需要使用动态数据透视表来构建它们。此外,我不会将您的列名称添加到条件inout,而是创建另一个名为in_out_flag的列来区分月份。

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

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(datename(month,c.hiredate)) 
            FROM [dbo].[#IPAddress] c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT DEPTNO, In_Out_Flag, ' + @cols + ' from 
            (
                select DEPTNO
                ,case 
                    when IPaddress between 1 and 10
                        then ''In''
                else ''Out''
                end as in_out_flag
                ,datename(month,HIREDATE) [month]
                ,IPAddress  
                from [#IPAddress] 
            ) x
            pivot 
            (
                 count(IPAddress)
                for [month] in (' + @cols + ')
            ) p '

EXEC sp_executesql @query;

Dynamic Pivot Demo