在SQL Server dynamic pivot中指定默认值
下面是针对我的需求的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,
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