AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 331465
Accepted
Bart Jonk
Bart Jonk
Asked: 2023-09-22 16:50:34 +0800 CST2023-09-22 16:50:34 +0800 CST 2023-09-22 16:50:34 +0800 CST

如何更好地使用WITH来参数化日期

  • 772

我喜欢使用 CTE 来创建漂亮且清晰的查询。但是,我很确定我创建的查询效率确实很低。

有没有更好的方法来做到这一点并使事情变得清晰?

with first_date as (
    -- selecting just 1 date 
    --    namely:  1 full year ago
    select (extract(year from current_date - interval '1 year')||'-01-01' )::date as date
    )
, last_date as (
    select date from star.dim_date where current_cal_day='Current'
)
, total_active_customers_ps_day as(
  select
        dd.date
        , dd.is_first_day_in_month
        , dd.is_last_day_in_month   
        , count(dc.id) as total_customers
    from first_date, last_date,
        star.dim_date dd
        -- join with dim_client, using first_subscription_start_date & last_subscription_end_date
        --   to get the ids of just the active clients 
        join star.dim_client dc on dd.date 
            between dc.first_subscription_start_date and coalesce(dc.last_subscription_end_date::date, '3000-01-01') 
            and dc.created <= dd.date
            and dc.first_subscription_start_date >= dc.created::date
    where 
        dd.date >= first_date.date
        and dd.date <= last_date.date
    group by 
        dd.date
        , dd.is_first_day_in_month 
        , dd.is_last_day_in_month   
)
select * from total_active_customers_ps_day ;

我认为我引起了一些笛卡尔连接,因为这个查询效率更高

with total_active_customers_ps_day as(
  select
        dd.date
        , dd.is_first_day_in_month
        , dd.is_last_day_in_month   
        , count(dc.id) as total_customers
    from 
        star.dim_date dd
        -- join with dim_client, using first_subscription_start_date & last_subscription_end_date
        --   to get the ids of just the active clients 
        join star.dim_client dc on dd.date 
            between dc.first_subscription_start_date and coalesce(dc.last_subscription_end_date::date, '3000-01-01') 
            and dc.created <= dd.date
            and dc.first_subscription_start_date >= dc.created::date
    where 
        dd.date >=  (extract(year from current_date - interval '1 year')||'-01-01' )::date
        and dd.date <= (select date from star.dim_date where current_cal_day='Current')
    group by 
        dd.date
        , dd.is_first_day_in_month 
        , dd.is_last_day_in_month   
)
select * from total_active_customers_ps_day ;
 

有什么更好的方法来做到这一点?

postgresql
  • 1 1 个回答
  • 73 Views

1 个回答

  • Voted
  1. Best Answer
    Timmetje
    2023-09-22T17:32:00+08:002023-09-22T17:32:00+08:00

    WHERE您可以在查询开始时在公用表表达式 (CTE) 中计算一次结束日期,而不是在子句中使用子查询来获取结束日期,这与您对开始日期所做的操作类似。这降低了子句的复杂性WHERE,并可能使查询更加高效。

    star.dim_date表与 CTEstart_date和之间确实存在笛卡尔连接end_date。这可能会导致性能问题,尤其是在star.dim_date表包含大量行的情况下。

    为了避免笛卡尔联接并使查询更高效,您可以使用单个 CTE 来计算开始日期和结束日期,然后将此 CTE 与表联接star.dim_date。

    另外,我还使用该DATE_TRUNC函数从当前日期计算一年前的开始日期,这可以使查询更加直观。

    WITH date_range AS (
        SELECT
            (DATE_TRUNC('YEAR', CURRENT_DATE) - INTERVAL '1 YEAR')::DATE AS start_date,
            DATE_TRUNC('DAY', CURRENT_DATE) AS end_date
    ),
    
    total_active_customers_per_day AS (
        SELECT
            dd.date,
            dd.is_first_day_in_month,
            dd.is_last_day_in_month,
            COUNT(dc.id) AS total_customers
        FROM
            star.dim_date dd
        JOIN
            star.dim_client dc ON dd.date BETWEEN dc.first_subscription_start_date AND COALESCE(dc.last_subscription_end_date::DATE, '3000-01-01')
                AND dc.created <= dd.date
                AND dc.first_subscription_start_date >= dc.created::DATE
        JOIN
            date_range ON dd.date BETWEEN date_range.start_date AND date_range.end_date
        GROUP BY
            dd.date,
            dd.is_first_day_in_month,
            dd.is_last_day_in_month
    )
    
    SELECT * FROM total_active_customers_per_day;
    

    确保JOIN条件和WHERE子句中使用的列已正确建立索引。在您的情况下,对dd.date、dc.first_subscription_start_date、 等列建立索引dc.last_subscription_end_date可以显着提高查询性能。

    • 2

相关问题

  • 我可以在使用数据库后激活 PITR 吗?

  • 运行时间偏移延迟复制的最佳实践

  • 存储过程可以防止 SQL 注入吗?

  • PostgreSQL 中 UniProt 的生物序列

  • PostgreSQL 9.0 Replication 和 Slony-I 有什么区别?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve