SQL Server,pivot未指定的列数和行数

时间:2018-03-13 05:42:24

标签: sql sql-server-2012 pivot

我每天都在查询每扇门的入口数量。

首先,我查询人数进入由“door_code列”标识的相关门并传递pass_id列标识的密钥id。所以我将“pass_id”列分组以删除入口处的重复人物。

SELECT 
    t1.[entrance_date],
    [door_code],
    COUNT([pass_id]) AS [entrance_count]
FROM
    (SELECT
         CONVERT(date, substring(entrance_date, 0, 9)) as [entrance_date],   
         [pass_id], [door_code]
     FROM
         dbo.entrance_history
     WHERE
         door_code IN ('000A', '000B', '000C'....continued)
     GROUP BY
         CONVERT(date, substring(entrance_date, 0, 9)), [pass_id], [door_code]) t1
WHERE
    t1.entrance_date BETWEEN '2018-03-10' AND '2018-03-13' 
GROUP BY 
    [door_code], [entrance_date]
ORDER BY 
    [door_code] DESC, [entrance_date] DESC

此查询返回如下结果集:

entrance_date|door_code|entrance_count
2018-03-13   |000C     |9
2018-03-12   |000C     |23
2018-03-11   |000C     |18
2018-03-10   |000C     |19
2018-03-13   |000B     |1
2018-03-12   |000B     |1
2018-03-11   |000B     |1
2018-03-10   |000B     |1
2018-03-12   |000A     |1
.....continued

我想像

那样改造它
entrance_date|000C|000B|000A
2018-03-13   |9   |1   |0
2018-03-12   |23  |1   |1
2018-03-11   |18  |1   |1
2018-03-10   |19  |1   |1

我尝试了如下所示的枢轴,但它不起作用。 我正在使用SQL Server 2012.

declare @doorCode nvarchar(Max) = '''000A'',''000B'',''000C'''
declare @sql nvarchar(Max);

set @sql = 'select base_table.[enterance_date], '
+ @doorCode +
' from
(SELECT t1.[entrance_date],
[door_code],
count([pass_id]) as [entrance_count]
FROM
(
    select CONVERT(date,substring(entrance_date,0,9)) as [entrance_date], [pass_id], [door_code]
    from dbo.entrance_history
    where door_code in ('+@doorCode+')
    group by CONVERT(date,substring(entrance_date,0,9)),[pass_id], [door_code]
) t1
group by [door_code], [entrance_date]
) as [base_table]
    pivot 
    (
      base_table.enterance_count 
      for base_table.[door_code] in ('+@doorCode+')
    ) as pivottable'

exec sp_executesql @sql

2 个答案:

答案 0 :(得分:0)

检查此查询。我相信一个分组就足够了

declare @doorCode nvarchar(Max) = '''000A'',''000B'',''000C'''
declare @doorCode2 nvarchar(Max) = '[000A],[000B],[000C]'
declare @sql nvarchar(Max);

set @sql = '
    select
        entrance_date, ' + @doorCode2 + '
    from (
        select 
            CONVERT(date,substring(entrance_date,0,9)) as [entrance_date], count([pass_id]) as [entrance_count], [door_code]
        from 
            dbo.entrance_history
        where 
            door_code in (' + @doorCode + ')
            group by CONVERT(date,substring(entrance_date,0,9)), [door_code]
    ) as [base_table]
    pivot (
        max([entrance_count]) for [door_code] in (' + @doorCode2 + ')
    ) as pvt
    '
exec sp_executesql @sql

答案 1 :(得分:0)

uzi的回答是部分正确的。虽然使用一个分组就足够了,但是传递ID必须包含在分组子句中,因此我们可以删除重复人员的入口记录。我试图查询人数进入门口,而不是入口数量。

为此,我首先查询每个 pass_id 的入口数,如下面的数据集。

entrance_date|door_code|entrance_count|pass_id
2018-03-13   |000C     |4             |P0001
2018-03-13   |000C     |2             |P0002
2018-03-13   |000C     |1             |P0003
2018-03-13   |000C     |1             |P0004
2018-03-13   |000B     |1             |P0001
2018-03-13   |000B     |1             |P0002
2018-03-13   |000B     |1             |P0003
2018-03-13   |000B     |1             |P0004
2018-03-13   |000A     |1             |P0001
.... continued

上面的结果由以下查询返回。

select 
  CONVERT(date,substring(entrance_date,0,9)) as [entrance_date],  [door_code], count([pass_id]) as [entrance_count], [pass_id]
  from dbo.entrance_history
  where door_code in ('000A', '000B', '000C'....continued)
  group by CONVERT(date,substring(entrance_date,0,9)), [door_code], [pass_id]

现在我需要在表格上方转动以获得我想要的数据集。为了获得人数(由“pass_id”列标识,根据每1人规则1次传递),我需要计算 pass_id。然后我得到了这个查询。

declare @doorCode nvarchar(Max) = '''000A'',''000B'',''000C'''
declare @doorCode2 nvarchar(Max) = '[000A],[000B],[000C]'
declare @sql nvarchar(Max);

set @sql = '
  select entrance_date, ' + @doorCode2 + '
  from (
    select 
      CONVERT(date,substring(entrance_date,0,9)) as [entrance_date],  [door_code], [pass_id]
      from dbo.entrance_history
      where door_code in ('+ @doorCode +')
      group by CONVERT(date,substring(entrance_date,0,9)), [door_code], [pass_id]
  ) as [base_table]
  pivot (
    count([pass_id]) 
    for [door_code] in ('+ @doorCode2 +')
  ) as [pvt] 
  order by entrance_date desc
'
exec sp_executesql @sql

然后返回我想要的数据集。

entrance_date|000A|000B|000C
2018-03-13   |9   |4   |1
2018-03-12   |23  |1   |1
2018-03-11   |18  |1   |1
2018-03-10   |19  |1   |1