PostgreSQL:公用表表达式和横向连接

时间:2016-01-13 21:38:44

标签: postgresql common-table-expression

我想实现这个:

with Period as
(
SELECT 
    dp.dtIni as dtRefPeriod,
    dp.dtEnd - p.days * interval '1 day' as dtIniWindow,
    dp.dtEnd,
    p.days
FROM public.vwDimPeriod dp
LEFT JOIN LATERAL ( select cast(vlParam as decimal(18,4)) as days
                    from public.DBParam
                    where cdparam = 'LifeTimeValueDays' ) p on TRUE
WHERE dp.dtEnd < CURRENT_DATE
)
,Orders as
(       
select 
    p.dtRefPeriod,
    o.nmEmail,
    dtOrder,
    p.dtIniWindow,
    p.dtEnd,
    o.cdOrder,
    o.vlOrder,
    p.days
from 
    public.vwFactOrder o
LEFT JOIN LATERAL Period p on TRUE
where
    ltrim(rtrim(o.nmEmail)) <> ''
    and o.blValid = B'1'
)
select * from Orders;

我收到了一个错误:

  

错误:语法错误在或附近&#34; p&#34;第1行:... rom public.vwFactOrder   o LEFT JOIN LATERAL期间p为TRUE ...                                                                ^(执行时间:219毫秒;总时间:437毫秒)

1 个答案:

答案 0 :(得分:0)

在您的查询中,您不使用LATERAL JOIN:使用先前指定关系的列来选择其他关系的列/行 - 那么为什么要使用它?此外,在此查询中使用CTE不是必需的或有用的,所以 - 除非您的查询中有些内容没有向我们展示 - 为什么不这样简单的查询:

SELECT
    dp.dtIni AS dtRefPeriod,
    o.nmEmail,
    o.dtOrder,
    dp.dtEnd - p.days * interval '1 day' AS dtIniWindow,
    dp.dtEnd,
    o.cdOrder,
    o.vlOrder,
    p.days
FROM
    public.vwFactOrder o
    LEFT JOIN public.vwDimPeriod dp
    LEFT JOIN ( SELECT cast(vlParam AS decimal(18,4)) AS days
                FROM public.DBParam
                WHERE cdparam = 'LifeTimeValueDays' ) p ON true
WHERE
    dp.dtEnd < CURRENT_DATE
    AND btrim(o.nmEmail) <> ''
    AND o.blValid;

请注意,您实际上是在进行交叉连接,因为您没有指定任何连接条件。在DBParam的情况下看似合理,因为它们看起来像参数值。如果是这样且参数始终存在且具有值,则不需要LEFT JOIN,而是更简单,更高效CROSS JOIN。但你肯定想要检查其他两个关系之间的连接条件。