在SQL Server dynamic pivot中指定默认值

在SQL Server dynamic pivot中指定默认值,sql,sql-server,date,sql-server-2008,pivot,Sql,Sql Server,Date,Sql Server 2008,Pivot,下面是针对我的需求的pivot查询 DECLARE @cols NVARCHAR(MAX) = ''; ;WITH log_date AS ( SELECT BatchStartDate AS l_date FROM Table_Batch_Lookup UNION ALL SELECT DATEADD(dd, 1, l_date) FROM log_date AS ld,

下面是针对我的需求的pivot查询

DECLARE @cols NVARCHAR(MAX) = '';

;WITH log_date AS 
(
    SELECT 
        BatchStartDate AS l_date 
    FROM 
        Table_Batch_Lookup

    UNION ALL

    SELECT 
        DATEADD(dd, 1, l_date) 
    FROM 
        log_date AS ld, Table_Batch_Lookup AS tb  
    WHERE 
        ld.l_date < DATEADD(dd, -1, tb.BatchEndDate)
)
SELECT 
    @cols = COALESCE (@cols + ',[' + CONVERT(NVARCHAR,CONVERT(VARCHAR(10), l_Date, 111), 106) + ']','[' + CONVERT(NVARCHAR, l_Date, 106) + ']') 
FROM 
    (SELECT DISTINCT CONVERT(VARCHAR(10), l_Date, 111) AS l_date 
     FROM log_date) PV;

DECLARE @totalScore INT = LEN(@cols) - LEN(REPLACE(@cols, ',', ''))

DECLARE @query NVARCHAR(MAX); 

SET @query = 'SELECT t_info.TraineeID,t_batch.BatchId,t_info.Name,t_info.Mobile'+@cols+'  FROM  Table_TraineeInfo AS t_info  Left JOIN       
                  (SELECT * FROM 
                 (
                     SELECT TraineeID,BatchId,Attendance,CONVERT(VARCHAR(10), l_Date, 111) AS l_date FROM Table_Attendance_Log
                 ) x
                 PIVOT 
                 (
                     MAX(Attendance)
                     FOR l_Date IN (' + right(@cols, len(@cols)-1)+ ')
                ) p ) AS f_pv ON t_info.TraineeID=f_pv.TraineeID JOIN Table_Batch_Lookup as t_batch ON t_batch.BatchId=t_info.BatchId

                WHERE t_batch.BatchId=45;
                ' ;    
    EXEC SP_EXECUTESQL @query;
我的电流输出

如果日期小于或等于今天,我希望下面的输出日期填充空值到缺席过去日期和未来日期应类似于2019年12月16日无缺席是未来日期无需填充缺席


在常规ie非动态透视查询中,当聚合函数生成null时,通常使用COALESCE来指定默认值

这对于动态SQL来说有点复杂。基本上,您需要设置第二个变量来保存要放入SELECT子句中的合并表达式。我称之为“选择”;我们使用COALESCE和CASE表达式,在指定默认值之前检查日期是否在将来

以下是您的更新代码:

Declare @cols NVARCHAR(Max)='';
Declare @select_cols NVARCHAR(Max)='';

;With log_date AS (
    SELECT BatchStartDate as l_date FROM Table_Batch_Lookup
    UNION ALL
    SELECT DATEADD(dd, 1, l_date)
    FROM log_date AS ld, Table_Batch_Lookup AS tb 
    WHERE ld.l_date < DATEADD(dd, -1, tb.BatchEndDate)
)
SELECT 
    @cols = COALESCE (
        @cols + ',[' + CONVERT(NVARCHAR,CONVERT(VARCHAR(10), l_Date, 111), 106) + ']',
        '[' + CONVERT(NVARCHAR, l_Date, 106) + ']'
    ), 
    @select_cols = COALESCE (
        @select_cols 
            + ',COALESCE([' + CONVERT(NVARCHAR,CONVERT(VARCHAR(10), l_Date, 111), 106) 
            + '], ' + CASE WHEN CONVERT(DATE, l_Date, 111) <= GETDATE() 
                THEN '''Absent''' 
                ELSE '''NULL''' 
            END + ') AS [' 
            + CONVERT(NVARCHAR,CONVERT(VARCHAR(10), l_Date, 111), 106) + ']',
        '[' + CONVERT(NVARCHAR, l_Date, 106) + ']'
    )
FROM (SELECT DISTINCT CONVERT(VARCHAR(10), l_Date, 111) AS l_date FROM log_date) PV

Declare @totalScore INT =len(@cols) - len(replace(@cols, ',', ''))

DECLARE @query NVARCHAR(MAX); 
SET @query = 'SELECT 
        t_info.TraineeID,
        t_batch.BatchId,
        t_info.Name,
        t_info.Mobile'
        + @select_cols + '
    FROM  Table_TraineeInfo AS t_info  
    LEFT JOIN (
            SELECT * FROM (
                 SELECT 
                     TraineeID,
                     BatchId,
                     Attendance,
                     CONVERT(VARCHAR(10), l_Date, 111) AS l_date 
                 FROM Table_Attendance_Log
            ) x
            PIVOT (
                 MAX(Attendance)
                 FOR l_Date IN (' + right(@cols, len(@cols)-1)+ ')
            ) p 
    ) AS f_pv ON t_info.TraineeID=f_pv.TraineeID 
    JOIN Table_Batch_Lookup as t_batch ON t_batch.BatchId=t_info.BatchId
    WHERE t_batch.BatchId=45';  

EXEC SP_EXECUTESQL @query;
:


我不希望2019/12/16日期缺席,因为它的未来日期,请检查我的输出@GMBMy输出不同@你在吗@欢迎你@mohdmazharkhan。我并不是那个对你的问题投反对票的人,我实际上是对它投了赞成票,因为我发现它很有趣,而且有很好的记录。
Declare @cols NVARCHAR(Max)='';
Declare @select_cols NVARCHAR(Max)='';

;With log_date AS (
    SELECT BatchStartDate as l_date FROM Table_Batch_Lookup
    UNION ALL
    SELECT DATEADD(dd, 1, l_date)
    FROM log_date AS ld, Table_Batch_Lookup AS tb 
    WHERE ld.l_date < DATEADD(dd, -1, tb.BatchEndDate)
)
SELECT 
    @cols = COALESCE (
        @cols + ',[' + CONVERT(NVARCHAR,CONVERT(VARCHAR(10), l_Date, 111), 106) + ']',
        '[' + CONVERT(NVARCHAR, l_Date, 106) + ']'
    ), 
    @select_cols = COALESCE (
        @select_cols 
            + ',COALESCE([' + CONVERT(NVARCHAR,CONVERT(VARCHAR(10), l_Date, 111), 106) 
            + '], ' + CASE WHEN CONVERT(DATE, l_Date, 111) <= GETDATE() 
                THEN '''Absent''' 
                ELSE '''NULL''' 
            END + ') AS [' 
            + CONVERT(NVARCHAR,CONVERT(VARCHAR(10), l_Date, 111), 106) + ']',
        '[' + CONVERT(NVARCHAR, l_Date, 106) + ']'
    )
FROM (SELECT DISTINCT CONVERT(VARCHAR(10), l_Date, 111) AS l_date FROM log_date) PV

Declare @totalScore INT =len(@cols) - len(replace(@cols, ',', ''))

DECLARE @query NVARCHAR(MAX); 
SET @query = 'SELECT 
        t_info.TraineeID,
        t_batch.BatchId,
        t_info.Name,
        t_info.Mobile'
        + @select_cols + '
    FROM  Table_TraineeInfo AS t_info  
    LEFT JOIN (
            SELECT * FROM (
                 SELECT 
                     TraineeID,
                     BatchId,
                     Attendance,
                     CONVERT(VARCHAR(10), l_Date, 111) AS l_date 
                 FROM Table_Attendance_Log
            ) x
            PIVOT (
                 MAX(Attendance)
                 FOR l_Date IN (' + right(@cols, len(@cols)-1)+ ')
            ) p 
    ) AS f_pv ON t_info.TraineeID=f_pv.TraineeID 
    JOIN Table_Batch_Lookup as t_batch ON t_batch.BatchId=t_info.BatchId
    WHERE t_batch.BatchId=45';  

EXEC SP_EXECUTESQL @query;
TraineeID | BatchId | Name | Mobile | 2019/12/13 | 2019/12/14 | 2019/12/15 | 2019/12/16 --------: | ------: | :------ | :--------- | :--------- | :--------- | :--------- | :--------- 243 | 45 | demo201 | 9888562341 | Present | Present | Present | NULL 244 | 45 | demo202 | 9888562342 | Absent | Absent | Present | NULL 246 | 45 | demo204 | 9888562344 | Absent | Present | Present | NULL 247 | 45 | demo205 | 9999999999 | Absent | Absent | Absent | NULL