按月学生出勤报表SQL查询

Student Attendance Report Month-wise SQL Query

有 3 个表 -

Attendance (EnrollmentNo,SubjectCode,Date,Attendance)

Student (EnrollmentNo, RollNo), 

UserDetails(EnrollmentNo,FirstName,LastName).

现在我想要的是按月显示出勤率,以 Roll No、Name、dates 为列和 Student.RollNo、UserDetails.FirstName、UserDetails.LastName、Attendance.Attendance分别作为列的数据。

但我面临的问题是如何动态生成日期列并将考勤数据放入相应的日期列中。

Input - Startdate and Enddate

Expected Output -
-------------------------------------------------------
| Roll No |       Name       | 01-09-2018 | 01-12-2018|
-------------------------------------------------------
|    15   |   Suyash Gupta   |     1      |     0     |
-------------------------------------------------------
|    24   |  Himanshu Shukla |     2      |     2     |
-------------------------------------------------------
|    32   | Dhruv Raj Sirohi |     1      |     1     |
-------------------------------------------------------

这是我的方法 -

DECLARE @startdate date
DECLARE @enddate date

SET @startdate = convert(date,'01-09-2018')
SET @enddate = convert(date,'01-12-2018')

;with cte (@startdate, @enddate) as /*I don't know how to pass my date range 
                                    in cte() as this takes table column*/
(
    select 1
    union all
    select dateadd(dd, 1, startdate)
    from cte
    where startdate <= enddate
) 
select c.startdate
into #tempDates
from cte c


select @cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(CHAR(10), 
startdate, 120)) 
                    from #tempDates
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT RollNo,FirstName,LastName, ' + @cols + ' from 
             (
                select S.RollNo,U.FirstName,U.LastName,
                D.startdate,
                convert(CHAR(10), startdate, 120) PivotDate
                from #tempDates D
                left join Attendance A
                on D.startdate = A.Date
            ) x
           pivot 
           (
                count(startdate)
                for PivotDate in (' + @cols + ')
           ) p '

execute(@query)

你的意思是这样的吗:

DECLARE @StartDate AS DATETIME, @EndDate AS DATETIME
SET @StartDate='2018-01-01'
SET @EndDate='2018-01-10'

SELECT Student.RollNo, Student.FirstName, Student.LastName, Attendance.Date
FROM Attendance,Student,UserDetails
WHERE Attendance.EnrollmentNo=Student.EnrollmentNo
AND UserDetails.EnrollmentNo=Student.EnrollmentNo
AND Attendance.[Date] between @StartDate and @EndDate

更新

根据您在问题中所说的,您可能需要以下代码:

SELECT Student.RollNo, Student.FirstName, Student.LastName, 
STUFF((SELECT  ','+CAST([DATE] AS VARCHAR(30))
FROM Attendance
WHERE Attendance.EnrollmentNo=Student.EnrollmentNo
AND Attendance.[Date] between @StartDate AND @EndDate
FOR XML PATH('')
), 1, 1, '') Dates
FROM Student,UserDetails
WHERE UserDetails.EnrollmentNo=Student.EnrollmentNo

你的代码有一些问题,看看我的代码的不同之处:

DECLARE @startdate date = '20180109';
DECLARE @enddate date = '20180112';
DECLARE @cols as varchar(2000);
DECLARE @query as varchar(MAX);

WITH cte (startdate)
AS 
(SELECT
        @startdate AS startdate
    UNION ALL
    SELECT
        DATEADD(DAY, 1, startdate) AS startdate
    FROM cte
    WHERE startdate < @enddate)

SELECT
    @cols = STUFF((SELECT DISTINCT
            ',' + QUOTENAME(CONVERT(CHAR(10),
            startdate, 120))
        FROM cte
        FOR XML PATH (''), TYPE)
    .value('.', 'NVARCHAR(MAX)')
    , 1, 1, '')

SET @query = 'SELECT RollNo,FirstName,LastName, ' + @cols + ' from 
             (
                select S.RollNo,U.FirstName,U.LastName,
                D.startdate,
                convert(CHAR(10), startdate, 120) PivotDate
                from #tempDates D
                left join Attendance A
                on D.startdate = A.Date
            ) x
           pivot 
           (
                count(startdate)
                for PivotDate in (' + @cols + ')
           ) p '

EXECUTE (@query)

这是 运行 代码并为我提供了所需的输出。我要感谢纠正我的 Lobo,以及所有付出努力帮助我的人。感谢大家和 Whosebug 为我提供了平台来查询我面临的问题。

DECLARE @startdate date = '20180109';
DECLARE @enddate date = '20180112';
DECLARE @cols as varchar(2000);
DECLARE @query as varchar(MAX);

WITH cte (startdate)
AS 
(SELECT
        @startdate AS startdate
    UNION ALL
    SELECT
        DATEADD(DAY, 1, startdate) AS startdate
    FROM cte
    WHERE startdate < @enddate
)
select c.startdate
into #tempDates
from cte c

SELECT
    @cols = STUFF((SELECT DISTINCT
            ',' + QUOTENAME(CONVERT(CHAR(10),
            startdate, 120))
        FROM #tempDates
        FOR XML PATH (''), TYPE)
    .value('.', 'NVARCHAR(MAX)')
    , 1, 1, '')

SET @query = 'SELECT RollNo,FirstName,LastName, ' + @cols + ' from 
             (
                select S.RollNo,U.FirstName,U.LastName,
                D.startdate,
                convert(CHAR(10), startdate, 120) PivotDate
                from #tempDates D,Attendance A, Student S, UserDetails U
                where D.startdate = A.Date and A.EnrollmentNo=S.EnrollmentNo and A.EnrollmentNo=U.userID
            ) x
           pivot 
           (
                count(startdate)
                for PivotDate in (' + @cols + ')
           ) p '

EXECUTE (@query)
drop table #tempDates