将多项选择查询更改为CTE查询

时间:2019-06-06 17:31:00

标签: sql oracle common-table-expression

我想将此特定的简单选择查询更改为CTE以对其进行优化,因为此简单的三选择查询需要4分钟,因此,我想通过将其转换为CTE查询来减少执行时间。

select sum(AMOUNT) usd from data where status IN ('ACCEPTED','REJECTED','CANCELLED') and date between '01-SEP-18' and '30-NOV-18' 
UNION 
select sum(AMOUNT) usd from data where status IN ('ACCEPTED','REJECTED','CANCELLED') and date between '01-NOV-18' and '31-JAN-19' 
UNION 
select sum(AMOUNT) usd from data where status IN ('ACCEPTED','REJECTED','CANCELLED') and date between '01-FEB-19' and '30-APR-19' 
ORDER BY usd DESC ;

预期结果应该是一列,显示三个查询的结果,这是此查询中金额的总和。

示例:

USD
100 (timeline 1)
200 (timeline 2)
300 (timeline 3)

我尝试过的一个: 您可以用总和而不是计数来转换CTE查询吗?

WITH cte AS (
    SELECT
        COUNT(CASE WHEN status_date BETWEEN '2018-11-01' AND '2019-01-31' THEN 1 END) AS cnt1,
        COUNT(CASE WHEN status_date BETWEEN '2019-02-01' AND '2019-04-30' THEN 1 END) AS cnt2,
        COUNT(CASE WHEN status_date BETWEEN '2019-05-01' AND '2019-07-31' THEN 1 END) AS cnt3
    FROM data
    WHERE status IN ('ACCEPTED', 'REJECTED', 'CANCELLED')
)

SELECT cnt1 FROM cte
UNION ALL
SELECT cnt2 FROM cte
UNION ALL
SELECT cnt3 FROM cte;

1 个答案:

答案 0 :(得分:0)

我猜您不希望时间线重叠,所以:

select (case when date between '01-SEP-18' and '30-NOV-18' then 'timeline1'
             when date between '01-DEC-18' and '31-JAN-19' then 'timeline2'
             when date between '01-FEB-19' and '30-APR-19' then 'timeline3'
        end), sum(AMOUNT) as usd
from data
where status IN ('ACCEPTED','REJECTED','CANCELLED') and 
     date between '01-SEP-18' and '30-APR-19'
group by (case when date between '01-SEP-18' and '30-NOV-18' then 'timeline1'
               when date between '01-DEC-18' and '31-JAN-19' then 'timeline2'
               when date between '01-FEB-19' and '30-APR-19' then 'timeline3'
        end)
order   by usd desc;

如果这样做,单独的列可能会更简单:

select sum(case when date >= date '2018-09-01' and date < date '2018-12-01' then amount end) as usd_timeline1,
       sum(case when date >= date '2018-11-01' and date < date '2019-02-01' then amount end) as usd_timeline2
       sum(case when date >= date '2019-02-01' and date '2019-05-01' then amount end) as usd_timeline3
from data
where status IN ('ACCEPTED','REJECTED','CANCELLED') and 
      date >= date '2018-09-01' and date < date '2019-05-01'
order by usd desc;

请注意,它使用ISO标准YYYY-MM-DD格式和date关键字使用日期常量。