Postgresql-没有CTE你能做到这一点吗?

Postgresql-没有CTE你能做到这一点吗?,sql,postgresql,Sql,Postgresql,我想了解客户在最初订单的前7天内的订单数量和花费。我设法用一个公共表表达式实现了这一点,但很好奇是否有人能指出主查询的WHERE或HAVING部分,或者子查询的明显更新 --This is a temp table to use in the main query WITH first_seven AS ( select min(o.created_at), min(o.created_at) + INTERVAL '7 day' as max_order_date, o.u

我想了解客户在最初订单的前7天内的订单数量和花费。我设法用一个公共表表达式实现了这一点,但很好奇是否有人能指出主查询的WHERE或HAVING部分,或者子查询的明显更新

--This is a temp table to use in the main query
WITH first_seven AS 

    (
    select min(o.created_at), min(o.created_at) + INTERVAL '7 day' as max_order_date, o.user_id
    from orders o
    where o.total_price > 0 and o.status = 30
    group by o.user_id
    having min(o.created_at) > '2015-09-01' 
    )


--This is the main query, find orders in first 7 days of purchasing

SELECT sum(o.total_price) as sales, count(distinct o.objectid) as orders, o.user_id, min(o.created_at) as first_order
from orders o, first_seven f7 
where o.user_id = f7.user_id and o.created_at < f7.max_order_date and o.total_price > 0 and o.status = 30
group by o.user_id
having min(o.created_at) > '2015-09-01'

通过使用窗口函数,您可以在不使用联接的情况下执行此操作:

select sum(o.total_price) as sales, count(distinct o.objectid) as orders,
       o.user_id, min(o.created_at) as first_order
from (select o.*,
             min(o.created_at) over (partition by user_id) as startdate
      from orders o
      where o.total_price > 0 and o.status = 30 
     ) o
where startdate > '2015-09-01' and
      created_at <= startdate + INTERVAL '7 day';
使用正确索引的更复杂查询可能更高效:

select sum(o.total_price) as sales, count(distinct o.objectid) as orders,
       o.user_id, min(o.created_at) as first_order
from (select o.*,
             min(o.created_at) over (partition by user_id) as startdate
      from orders o
      where o.total_price > 0 and o.status = 30 and
            not exists (select 1 from orders o2 where o2.user_id = o.user_id and created_at <= '2015-09-01')
     ) o
where startdate > '2015-09-01' and
      created_at <= startdate + INTERVAL '7 day';

这会在windows计算之前过滤掉老客户,这会使计算更高效。有用的索引包括ordersuser\u id、created\u at和ordersstatus、total\u price。

如果您不提供至少一个表DDL、一些数据样本、预期结果和PostgreSQL版本,那么没有人能帮到您。如果您愿意,可以将其转换为子查询。顺便说一下,不要在from子句中使用逗号。始终使用显式连接语法。它只是一个包含事务、orderid、customerid、orderdate和TotalPrice的标准表。最佳查询取决于表定义。始终提供您的Postgres版本和显示数据类型和约束的表定义:创建表脚本或您在psql中获得的命令。如果没有基本信息,这个问题对其他人几乎没有用处。创建的_at的数据类型特别重要。谢谢@ErwinBrandstetter-我没有想到会包括这些细节,但将来会。真知灼见