【问题标题】:How to optimize a query that compares data from the same day for each month如何优化比较每个月同一天的数据的查询
【发布时间】:2022-10-02 16:25:15
【问题描述】:

我有一个查询,它从给定日期获取数据并将其与每个月的同一工作日进行比较(如果它变成星期六、星期日或假期,它应该显示前一天的最后一天,即如果我说 25,它将返回2022 年 9 月 23 日,9 月和 8 月 25 日,8 月等)。 DAILY_DATA 表仅包含工作日,因此有效:

SELECT *
FROM DAILY_DATA A, --It has partitions for every day, like \'PART_300922\'
(   SELECT TO_CHAR(DATE,\'MM\'),MAX(DATE) DATE
    FROM DAILY_DATA
    WHERE TO_CHAR(DATE,\'YYYY\')=\'2022\'
    AND TO_CHAR(DATE,\'DD\')<=TO_CHAR(TO_DATE(&query_date),\'DD\')
    GROUP BY TO_CHAR(DATE,\'MM\')
    )B
WHERE A.DATE = B.DATE
ORDER BY 1;

问题是,它需要很长时间才能循环整个表,有没有办法优化它?也许使用分区或其他东西? 请帮忙。

  • 您不能优化在 SELECT 语句中使用子查询的任何内容,因为该子查询必须针对表的每一行执行。此外,对TO_CHAR 的重复函数调用也会减慢执行速度。

标签: oracle oracle12c


【解决方案1】:

尝试这个:

WITH prep_daily_data(dat, dim, mdat) AS (
    SELECT 
        d.dat, 
        TO_CHAR( d.dat , 'DD'),
        TO_NUMBER(TO_CHAR(d.dat,'YYYYMM')) as mdat
    FROM daily_data d
),
matching_dim(dat, next_dat) AS (
    SELECT cm.dat, nm.dat
    FROM prep_daily_data cm
    JOIN prep_daily_data nm ON cm.dim = nm.dim AND cm.mdat+1 = nm.mdat
),
matching_others(dat, next_dat) AS (
    SELECT dat, MAX(next_dat) FROM (
        SELECT cm.dat AS dat, nm.dat AS next_dat
        FROM prep_daily_data cm
        JOIN prep_daily_data nm ON cm.dim > nm.dim AND cm.mdat+1 = nm.mdat
        WHERE NOT EXISTS(SELECT 1 FROM matching_dim d WHERE d.dat = cm.dat)
    ) 
    GROUP BY dat
)
SELECT * FROM (
    SELECT * FROM matching_dim
    UNION ALL
    SELECT * FROM matching_others
)
ORDER BY dat
;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    相关资源
    最近更新 更多