1

我有一个动态 PIVOT 查询,其中动态生成列。

我的表:ATTENDANCE_MASTER 包含:ID、Stud_id、ATT_DATE、PRESENT

它存储如下数据:

ID  Stud_id ATT_DATE   PRESENT
1     1     2015-08-1    1
2     2     2015-08-1    0
3     3     2015-08-1    1
4     1     2015-08-2    0
5     2     2015-08-2    1
6     3     2015-08-2    1

我需要这样的结果

Stud_ID  2015-08-01   2015-08-2 2015-08-3 Total  Count
1            1            0         1      2      3
2            1            1         1      3      3
3            1            1         0      2      3
4            0            0         1      1      3

我创建了 PIVOT 查询

DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX),@columns1 NVARCHAR(MAX);   

SELECT  @columns = N'',@columns1 =N'';
SET @Columns = (SELECT  N', p.' + QUOTENAME(REPLACE(CONVERT(VARCHAR(10), p.Att_Date, 111), '/', '-'))
                FROM  ATTENDANCE_MASTER AS p
                GROUP BY p.ATT_DATE
                ORDER BY p.ATT_DATE
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)');

SET @sql = N'SELECT Stud_id, ' + STUFF(@columns, 1, 2, '') + ', Total = ' + STUFF(REPLACE(@columns, ', p.[', ' + p.['), 1, 3, '') + '
, Outof = ' + STUFF(REPLACE(@columns1, ', p1.[', ' + p1.['), 1, 4, '') + '
FROM
(
  SELECT p.ATT_DATE, p.Stud_id, p.PRESENT FROM ATTENDANCE_MASTER AS p
) AS j
PIVOT
(
  SUM(PRESENT) FOR ATT_DATE IN ('+ STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '') + ')
) AS p;
PIVOT
(
  Count(PRESENT) FOR ATT_DATE IN ('+ STUFF(REPLACE(@columns1, ', p1.[', ',['), 1, 1, '') + ')
) AS p1;';
PRINT @sql;
EXEC sp_executesql @sql;

我尝试了很多,但没有解决方案。我可以在这个查询中使用两个聚合函数吗?请建议我解决方案。

提前致谢。

4

1 回答 1

2

您可以使用公用表表达式来实现此目的。例如 你的桌子是

create table [student_Register]
(
ID int not null unique identity(1,1),
  Stud_id int not null ,
   ATT_DATE varchar(50) not null,
     PRESENT int not null
)

和价值观

insert into student_Register
select 1, '01-08-2015', 1 union all
select 2, '01-08-2015', 0 union all
select 3, '01-08-2015', 0 union all
select 1, '02-08-2015', 0 union all
select 2, '02-08-2015', 0 union all
select 3, '02-08-2015', 1 union all
select 1, '03-08-2015', 1 union all
select 2, '03-08-2015', 0 union all
select 3, '03-08-2015', 0 union all
select 1, '04-08-2015', 0 union all
select 2, '04-08-2015', 0 union all
select 3, '04-08-2015', 1 UNION ALL
select 1, '05-08-2015', 1 union all
select 2, '05-08-2015', 0 union all
select 3, '05-08-2015', 0 

查询获取单个字符串中的 ATT_DATE 值

DECLARE @cols AS NVARCHAR(MAX)
DECLARE  @query  AS NVARCHAR(MAX)
DECLARE @SEPERATOR as VARCHAR(1) 
DECLARE @SP  INT
DECLARE @VALUE VARCHAR(MAX)
DECLARE @INSTR VARCHAR(MAX)
DECLARE @ORGSTR VARCHAR(MAX)
DECLARE @COLSREV VARCHAR(MAX)


SET @SEPERATOR = ','
SET @COLSREV = ''

--use stuff you can get full value of ATT_Date As single string

SET @ORGSTR = STUFF((SELECT distinct ',' + QUOTENAME([ATT_DATE]) 
            FROM dbo.student_Register 
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

SET @INSTR = ''+@ORGSTR +','

在这里插入 MIn() fun 到每个 ATT_Date 值

----------LOOP FOR INSERT MIN() FUNCTION IN TO THE INTSQR
WHILE PATINDEX('%' + @SEPERATOR + '%', @INSTR ) <> 0 
BEGIN
   SELECT  @SP = PATINDEX('%' + @SEPERATOR + '%',@INSTR)  --LENGTH OF FIRST STRING SET INCLUDE COMMA
    SELECT  @COLS = LEFT(@INSTR , @SP - 1)              -- TAKE FIRST SET
    SET @COLS =  'min('+@COLS+') AS '+@COLS+'';         --ADD FUN IN FIRST SET
   SELECT  @INSTR = STUFF(@INSTR, 1, @SP, '')           -- REMOVE FIRST SET STRING FROM @INSTR
    --INSERT INTO #tempTab (id) VALUES (@COLS)
   SET @COLSREV +=''+@COLS+','
  END ----LOOP END

  set @COLSREV = STUFF(@COLSREV,LEN(@COLSREV),1,'')

使用 Pivot 的主要动态查询

set @query = 'SELECT  Stud_id, '+@COLSREV+'   from(  select * from student_Register  ) 
    x 
        pivot 
        (
         min([PRESENT])

for [ATT_DATE] in ('+@ORGSTR+')
) As p


  group by [Stud_id] '

最后使用带有 [DAYS OF PRESENT] 和 [Total Days] 的 CTE 合并数据透视查询

set @query = 'with mycte
    As
    (

    '+@query+'

    ),
     mycte1
    As(
    SELECT Stud_id, COUNT(PRESENT) AS [TOTAL DAYS], SUM(PRESENT) AS [DAYS OF PRESENT] FROM student_Register GROUP BY Stud_id
    )

    select mycte1.Stud_id, '+@ORGSTR+' , mycte1.[TOTAL DAYS], mycte1.[DAYS OF PRESENT] from mycte
left join mycte1 on mycte.Stud_id = mycte1.Stud_id'

    execute sp_executesql @query;

这是我的小提琴示例: 带 Pivot 的 Dynamic_String

于 2016-05-25T04:52:04.847 回答