重写为单个查询
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'
以上可能会为您提供更紧凑的语法。但是,如果您依赖日期列上的索引,那么上述内容实际上可能会损害您的性能。如果您决定尝试,请确保您对此进行了分析。
我必须将要合并到一个查询中的 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'
以上可能会为您提供更紧凑的语法。但是,如果您依赖日期列上的索引,那么上述内容实际上可能会损害您的性能。如果您决定尝试,请确保您对此进行了分析。