在数据透视查询结果中将0替换为N / A或-1

时间:2018-01-12 19:33:22

标签: sql sql-server sql-server-2014

我有考勤表,其中存储了日期和出勤率,我在此查询中传递日期范围以显示出勤报告。

现在我的问题是如何用N / A或-1替换0(如果传递的日期与考勤表内的日期不匹配,我将其作为输出)?

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 '

1 个答案:

答案 0 :(得分:2)

你可以像Brandon Miller建议的那样使用CASE。这是另一个选项 - 您可以使用NULLIF将零替换为空值,然后将任何空值替换为N / A.您需要创建第二个变量来表示动态查询的select语句中的列。以下是测试数据的完整示例:

-- test data
create table #tempDates (startdate date)
create table Attendance (date date, enrollmentno int)
create table Student (rollno int, enrollmentno int)
create table UserDetails (FirstName varchar(10), LastName varchar(10), userid int)

insert into #tempDates values ('1/1/2018')
insert into Attendance values ('1/1/2018', 1)
insert into Student values (1, 1)
insert into UserDetails values ('J', 'S', 1)

declare @cols varchar(100) = '[2018-01-01],[2018-01-02]'
declare @cols_select varchar(500) = 'ISNULL(NULLIF(CAST([2018-01-01] AS VARCHAR(10)), ''0''), ''N/A'') AS [2018-01-01],ISNULL(NULLIF(CAST([2018-01-02] AS VARCHAR(10)), ''0''), ''N/A'') AS [2018-01-02]'

DECLARE @query nvarchar(max)
SET @query = 'SELECT RollNo,FirstName,LastName, ' 
    + @cols_select
    + '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 '

EXEC sp_executesql @query

输出:

RollNo  FirstName   LastName    2018-01-01  2018-01-02
1       J           S           1           N/A

为了好玩,这里有一个可以用来将@cols变量转换为@cols_select变量的函数:

create function dbo.fn_convert_cols(@cols varchar(max)) returns varchar(max)
as
begin
    declare @col varchar(20)
    declare @cols_select varchar(max) = ''

    declare @idx int, @idx2 int
    select @idx = CHARINDEX('[', @cols), @idx2 = CHARINDEX(']', @cols)
    while @idx > 0 and @idx2 > 0
    begin
        select @col = SUBSTRING(@cols, @idx + 1, @idx2 - @idx - 1)
        select @cols_select += ',ISNULL(NULLIF(CAST([' + @col + '] AS VARCHAR(10)), ''0''), ''N/A'') AS [' + @col + ']' 
        select @cols = SUBSTRING(@cols, @idx2 + 1, len(@cols) - @idx2)
        select @idx = CHARINDEX('[', @cols), @idx2 = CHARINDEX(']', @cols)
    end

    select @cols_select = SUBSTRING(@cols_select, 2, len(@cols_select) - 1) 
    return @cols_select
end
go

现在,您可以在构建查询时调用该函数,如下所示:

SET @query = 'SELECT RollNo,FirstName,LastName, ' + dbo.fn_convert_cols(@cols)+ ' from