Snowflake cloud data platform 无法使用限制1计算不支持的子查询类型

Snowflake cloud data platform 无法使用限制1计算不支持的子查询类型,snowflake-cloud-data-platform,Snowflake Cloud Data Platform,提交以下内容既是为了分享最佳实践的信息,也是为了征求更多意见 问:我需要运行一个查询来获取交易的汇率。根据交易日期,我需要汇率历史记录表中的最新汇率,其中汇率的起始生效日期小于交易日期 基本上: SELECT t.Amount, t.TrxDate, t.Currency, ex.ExchangeRate FROM Transactions t LEFT JOIN LATERAL ( SELECT ExchangeRate FROM RateHistory h WHE

提交以下内容既是为了分享最佳实践的信息,也是为了征求更多意见

问:我需要运行一个查询来获取交易的汇率。根据交易日期,我需要汇率历史记录表中的最新汇率,其中汇率的起始生效日期小于交易日期

基本上:

SELECT  t.Amount, t.TrxDate, t.Currency, ex.ExchangeRate
FROM Transactions t
LEFT JOIN LATERAL (
    SELECT ExchangeRate 
    FROM RateHistory h
    WHERE t.TrxDate <= h.EffectiveDate AND t.Currency = h.Currency ORDER BY EffectiveDate DESC 
    LIMIT 1) ex
所以我们可以在子查询中使用LIMIT,LIMIT没有问题,问题在其他地方

尝试将查询分解为多个部分,分别运行每个部分,然后逐个组合以进行分析

对建议1的回应:子查询可以工作,但是问题在于左连接。我已经尝试了我的查询没有限制1,它工作良好。。。但它显然返回了太多的结果

建议2:我们使用侧向力的具体原因是什么

尝试使用with子句编写子查询,并稍后将其联接

对建议2的响应:使用横向,因为我需要子查询中正好有一条记录连接到事务表中的每条记录。横向允许条件聚合来实现这一点。我不太清楚你用WITH子句是什么意思。你是在建议CTE吗

建议3:也许您可以尝试删除横向,也可以使用MAX函数,而不是对子查询进行排序并获取限制,因为基本上您需要指定日期之后的最新速率,但这是MAX by date将为您提供的

SELECT t.Amount, t.TrxDate, t.Currency, ex.ExchangeRate
FROM Transactions t
LEFT JOIN (
SELECT MAX(h.EffectiveDate ), h.Currency
FROM RateHistory h
WHERE t.TrxDate <= h.EffectiveDate
AND t.Currency = h.Currency
GROUP BY h.Currency
) ex
对建议3的回应:因为我需要的是最长日期的汇率,所以我还需要在该子查询中选择汇率,这意味着它需要按分组,并且我将在相同的位置结束;连接太多


还有其他的建议和/或解决方法吗?

所以我把第一个侧面移到了一个可能没有问题的CTE上。 第二个方面是需要每个行的gl.tx_日期,因此如果您只是将JOIN放在让位于多行的位置上,然后使用ROW_编号实现您想要的限制为1的过滤器。这让我觉得这将是缓慢的,但应该工作

WITH cte_a AS (
    SELECT ap.reg_int_id
        ,ap.reg_seq_no
        ,MAX(ap.reference) AS reference
        ,MIN(aph.dist_dt) AS dist_dt
    FROM apdist ap
    LEFT OUTER JOIN aphist aph 
        ON ap.voucher_no = aph.voucher_no
    GROUP BY 1,2
)
SELECT Region,
   acct_no,
    trx_date, 
    source, 
    reference, 
    doc_no, 
    amount, 
    for_amt,
    reference2,
    reg_int_id, 
    reg_seq_no, 
    gl_curr_id, 
    chart_curr_id,
    reference3,
    dist_dt,
    cur_desc,
    exchng_rate
FROM (
    SELECT
        'SG' AS Region,
        CAST(gl.acct_no AS NUMERIC(12,6)) AS acct_no, 
        gl.trx_date, 
        source, 
        gl.reference, 
        doc_no, 
        gl.amount, 
        for_amt,
        reference2,
        gl.reg_int_id, 
        gl.reg_seq_no, 
        gl.curr_id AS gl_curr_id, 
        c.curr_id AS chart_curr_id,
        z.reference AS reference3,
        z.dist_dt,
        cur.cur_desc,
        ex.exchng_rate
        row_number() over (partition by gl.curr_id order by ex.exchng_dt DESC) as rn
    FROM gltrx  gl
    JOIN chart c 
        ON ROUND(c.acct_no,6) = ROUND(gl.acct_no,6)
    LEFT OUTER JOIN currencies cur ON gl.curr_id = cur.curr_id
    LEFT JOIN cte_a as z
        ON z.reg_int_id = gl.reg_int_id AND z.reg_seq_no = gl.reg_seq_no                  
    LEFT JOIN Curr_hist as ex
        ON ex.Curr_Id = gl.curr_id and ex.Exchng_Dt <= gl.trx_date 
    )
WHERE rn = 1;

使用窗口函数确保只获得一行

(SELECT Exchng_rate,
        RANK() OVER (ORDER BY exchng_dt DESC) as order 
        FROM    Curr_hist 
        WHERE Curr_Id = gl.curr_id
        AND Exchng_Dt <= gl.trx_date 
        ) 
where order=1
WITH cte_a AS (
    SELECT ap.reg_int_id
        ,ap.reg_seq_no
        ,MAX(ap.reference) AS reference
        ,MIN(aph.dist_dt) AS dist_dt
    FROM apdist ap
    LEFT OUTER JOIN aphist aph 
        ON ap.voucher_no = aph.voucher_no
    GROUP BY 1,2
)
SELECT Region,
   acct_no,
    trx_date, 
    source, 
    reference, 
    doc_no, 
    amount, 
    for_amt,
    reference2,
    reg_int_id, 
    reg_seq_no, 
    gl_curr_id, 
    chart_curr_id,
    reference3,
    dist_dt,
    cur_desc,
    exchng_rate
FROM (
    SELECT
        'SG' AS Region,
        CAST(gl.acct_no AS NUMERIC(12,6)) AS acct_no, 
        gl.trx_date, 
        source, 
        gl.reference, 
        doc_no, 
        gl.amount, 
        for_amt,
        reference2,
        gl.reg_int_id, 
        gl.reg_seq_no, 
        gl.curr_id AS gl_curr_id, 
        c.curr_id AS chart_curr_id,
        z.reference AS reference3,
        z.dist_dt,
        cur.cur_desc,
        ex.exchng_rate
        row_number() over (partition by gl.curr_id order by ex.exchng_dt DESC) as rn
    FROM gltrx  gl
    JOIN chart c 
        ON ROUND(c.acct_no,6) = ROUND(gl.acct_no,6)
    LEFT OUTER JOIN currencies cur ON gl.curr_id = cur.curr_id
    LEFT JOIN cte_a as z
        ON z.reg_int_id = gl.reg_int_id AND z.reg_seq_no = gl.reg_seq_no                  
    LEFT JOIN Curr_hist as ex
        ON ex.Curr_Id = gl.curr_id and ex.Exchng_Dt <= gl.trx_date 
    )
WHERE rn = 1;
(SELECT Exchng_rate,
        RANK() OVER (ORDER BY exchng_dt DESC) as order 
        FROM    Curr_hist 
        WHERE Curr_Id = gl.curr_id
        AND Exchng_Dt <= gl.trx_date 
        ) 
where order=1