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