重写为单个查询

Rewrite into single query

我必须将要合并到一个查询中的 select 个查询分开。意思是我希望我的输出格式如下:

第 1 栏 | col2

252 ---- 05

一个想法是编写一个 CTE,虽然这两个是小查询,但我还有大约 4 个类似的日期范围查询,我想避免使用一个或多个 CTES 来获取数据。

这是我的 select 个查询:

SELECT 
  count(*) as pastDueRepl   
FROM TBLPTS_APPDATA 
WHERE APPV_PTSSTATUS = '2'      
  AND (APPD_NEXTREPLDATE IS NOT NULL)   
  AND APPD_NEXTREPLDATE between DATEADD(Day,-30,GETDATE()) and GETDATE()

SELECT 
  count(*) as pastDueInsp   
FROM TBLPTS_APPDATA 
WHERE APPV_PTSSTATUS = '2'      
  AND (APPD_NEXTINSPDATE IS NOT NULL) 
  AND APPD_NEXTINSPDATE between DATEADD(Day,-30,GETDATE()) and GETDATE()    

向每个查询添加 0 列,然后 sum 超过 union 个:

SELECT SUM(pastDueRepl) as pastDueRepl, sum(pastDueInsp) as pastDueInsp  FROM(
  SELECT 
  count(*) as pastDueRepl   , 0 as pastDueInsp  
  FROM TBLPTS_APPDATA 
  WHERE APPV_PTSSTATUS = '2'        
  AND (APPD_NEXTREPLDATE IS NOT NULL)   
  AND APPD_NEXTINSPDATE between DATEADD(Day,-30,GETDATE()) and GETDATE()

  UNION ALL

  SELECT 
  0 as pastDueRepl, count(*) as pastDueInsp 
  FROM TBLPTS_APPDATA 
  WHERE APPV_PTSSTATUS = '2'        
  AND (APPD_NEXTINSPDATE IS NOT NULL) 
  AND APPD_NEXTINSPDATE between DATEADD(Day,-30,GETDATE()) and GETDATE()    
) t

这应该让你开始:

select case when APPD_NEXTREPLDATE is not null and APPD_NEXTINSPDATE is null then 'a'
when APPD_NEXTREPLDATE is null and APPD_NEXTINSPDATE is not null then 'b'
when APPD_NEXTREPLDATE is not null and APPD_NEXTINSPDATE is not null then 'c'
else 'd' end status
, count(*) records

from etc
where etc

group by case when APPD_NEXTREPLDATE is not null and APPD_NEXTINSPDATE is null then 'a'
when APPD_NEXTREPLDATE is null and APPD_NEXTINSPDATE is not null then 'b'
when APPD_NEXTREPLDATE is not null and APPD_NEXTINSPDATE is not null then 'c'
else 'd' end

详情取决于您的要求。

我会使用条件聚合并在聚合函数中使用不同的条件,因此对于匹配条件的每一行,将 1 添加到总和(用作计数):

SELECT 
    SUM(
       CASE 
        WHEN APPD_NEXTINSPDATE between DATEADD(Day,-30,GETDATE()) and GETDATE() 
          THEN 1 
         ELSE 0 
       END
    ) AS pastDueInsp,
    SUM(
       CASE 
        WHEN APPD_NEXTREPLDATE between DATEADD(Day,-30,GETDATE()) and GETDATE() 
          THEN 1 
        ELSE 0 
       END
    ) AS pastDueRepl   
FROM TBLPTS_APPDATA 
WHERE APPV_PTSSTATUS = '2';

或者您可以使用 union all 运算符合并语句,或者将每个语句用作派生的 table 或在 cte 中。这么多选择。

这是一种减少重复并减少必须对日期范围边界进行硬编码的次数的好方法:

  with DateRangeBoundaries as (select DATEADD(Day,-30,GETDATE()) as LowerBoundDate,
                                      GETDATE() as UpperBoundDate)
select count(case when t.APPD_NEXTREPLDATE between drb.LowerBoundDate and drb.UpperBoundDate
                  then 'X' end) as pastDueRepl,
       count(case when t.APPD_NEXTINSPDATE between drb.LowerBoundDate and drb.UpperBoundDate
                  then 'X' end) as pastDueInsp
  from TBLPTS_APPDATA t
  join DateRangeBoundaries drb on 1=1
 where t.APPV_PTSSTATUS = '2'

以上可能会为您提供更紧凑的语法。但是,如果您依赖日期列上的索引,那么上述内容实际上可能会损害您的性能。如果您决定尝试,请确保您对此进行了分析。