如果动态数据透视查询没有结果,如何添加默认空行

use*_*768 1 sql-server-2008

我执行此过程并在我的应用程序中显示结果。如果我的查询没有返回任何结果,我仍然需要打印出列标题,并且由于它是动态查询,我无法进行硬编码。我的查询运行良好,如果没有找到结果,我该如何添加 NULL 行。因此,例如,在这是执行 SP 的结果的情况下,SQL 返回列标题,我想添加一个空行。

TSB 编号 系统 1 系统 2 系统 3

   ALTER PROCEDURE  [dbo].[spExportServiceTSB]                            
    (@StartDate datetime,                            
    @EndDate datetime,                                   
    @SelectedSystemIDs nvarchar (2000) = NULL,    
    @SelectedTsbIDs nvarchar (2000) = NULL,   
    @UserRoleID int
    )                            
    AS  



DECLARE @PlatformID INT = NULL

IF(@SelectedSystemIDs = '')
BEGIN
SET @SelectedSystemIDs = NULL
END

IF(@SelectedTsbIDs = '')
BEGIN
SET @SelectedTsbIDs = '0'
END

IF(@UserRoleID = 1)    
 BEGIN     
  SET @PlatformID = 1     
  END  

IF(@UserRoleID = 2)  
BEGIN  
SET @PlatformID = 2  
END  

IF (@UserRoleID = 3)    
BEGIN    
SET @PlatformID = 12    
END   

IF(@UserRoleID = 4)
BEGIN 
SET @PlatformID = 3
END

IF(@UserRoleID = 5)
BEGIN 
SET @PlatformID = 4
END

IF(@UserRoleID = 6)
BEGIN 
SET @PlatformID = 0
END

DECLARE @PivotColumnHeaders NVARCHAR(MAX)

SELECT @PivotColumnHeaders =  
   COALESCE(
     @PivotColumnHeaders + ',[' +  cast(SystemFullName as Nvarchar) + ']',
     '[' + cast(SystemFullName as varchar)+ ']'
   )
FROM System 
WHERE (@SelectedSystemIDs IS NULL OR  System.ID IN(select  * from dbo.SplitInts_RBAR_1(@SelectedSystemIDs, ',')))     
AND ((@PlatformID =0) OR  (System.PlatformID = @PlatformID) OR (@PlatformID = 12 AND System.PlatformID <= 2))  

DECLARE @PivotTableSQL NVARCHAR(MAX)
SET @PivotTableSQL = N'
   SELECT *
   FROM (
     SELECT
       TSBNumber [TSBNumber],
       SystemFullName,
       ClosedDate
     FROM ServiceEntry 
     INNER JOIN System 
       ON ServiceEntry.SystemID = System.ID
     where
      (ServiceEntry.TSBNumber IS NOT NULL)
       AND 
       (ServiceEntry.ClosedDate IS NOT NULL)
       AND
       ( 
       (''' + @SelectedTsbIDs + ''' = '''+ '0' + ''') OR
         (ServiceEntry.TSBNumber in (select * from dbo.SplitStrings_Moden(''' + @SelectedTsbIDs + ''', ''' + ',' + ''')))
        )  
        AND (
         (''' + CAST(@PlatformID AS VARCHAR(10)) + ''' = '''+ '0' + ''') 
        OR(System.PlatformID = ''' + cast(@PlatformID as varchar(10)) + ''')
        OR(''' + CAST(@PlatformID AS VARCHAR(10)) + ''' = ''' + '12' + ''' AND System.PlatformID <=  ''' + '2' + ''')
        )
        AND
        (ServiceEntry.ClosedDate between ''' + convert(varchar(10), @StartDate, 120)  + '''  and   ''' +  convert(varchar(10), @EndDate, 120) + ''')

   ) AS PivotData
   PIVOT (
     MAX(ClosedDate)
     FOR SystemFullName IN (
       ' + @PivotColumnHeaders + '
     ) 
   ) AS PivotTable
' 



EXECUTE (@PivotTableSQL)
Run Code Online (Sandbox Code Playgroud)

为了解决上述问题,我尝试通过执行 UNION all 来添加空行,但出现此错误。我现在尝试添加一个空行,因此修改后的查询如下

All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.


   SELECT *
   FROM (
     SELECT
       TSBNumber [TSBNumber],
       SystemFullName,
       ClosedDate
     FROM ServiceEntry 
     inner JOIN System 
       ON ServiceEntry.SystemID = System.ID
     where
      (ServiceEntry.TSBNumber IS NOT NULL)
       AND 
       (ServiceEntry.ClosedDate IS NOT NULL)
       AND
       ( 
       ('145' = '0') OR
         (ServiceEntry.TSBNumber in (select * from dbo.SplitStrings_Moden('145', ',')))
        )  
        AND (
         ('1' = '0') 
        OR(System.PlatformID = '1')
        OR('1' = '12' AND System.PlatformID <=  '2')
        )
        AND
        (ServiceEntry.ClosedDate between '2014-09-29'  and   '2014-10-06')    


  UNION ALL 

  select
    NULL, ''
where NOT EXISTS( 

 SELECT
       TSBNumber [TSBNumber],
       SystemFullName,
       ClosedDate
     FROM ServiceEntry 
     inner JOIN System 
       ON ServiceEntry.SystemID = System.ID
     where
      (ServiceEntry.TSBNumber IS NOT NULL)
       AND 
       (ServiceEntry.ClosedDate IS NOT NULL)
       AND
       ( 
       ('145' = '0') OR
         (ServiceEntry.TSBNumber in (select * from dbo.SplitStrings_Moden('145', ',')))
        )  
        AND (
         ('1' = '0') 
        OR(System.PlatformID = '1')
        OR('1' = '12' AND System.PlatformID <=  '2')
        )
        AND
        (ServiceEntry.ClosedDate between '2014-09-29'  and   '2014-10-06')   



  )

   ) AS PivotData
   PIVOT (
     MAX(ClosedDate)
     FOR SystemFullName IN (
       [EP(+)12  -  A20 - 107D],[EP(+)13  -  AP20 109B],[EP(+)14  -  AP20 -407A]
     ) 
   ) AS PivotTable   
Run Code Online (Sandbox Code Playgroud)

And*_*y M 5

使用原始查询作为派生表,并将其外连接到虚拟行,仅引用主 SELECT 中的查询列:

SELECT
  q.*
FROM
  (SELECT NULL) AS d (dummy)
LEFT JOIN
  (
    your query
  ) AS q
ON
  1 = 1
;
Run Code Online (Sandbox Code Playgroud)

这几乎类似于单行的交叉连接,但在这种情况下,最终输出始终至少有一行。如果子查询不返回任何行,则其列在输出中将为空。