【问题标题】:How can use for loop in left join如何在左连接中使用for循环
【发布时间】:2023-02-22 17:43:19
【问题描述】:

我有一个 tbl_ledger_input 表,其中包含许多我想插入的列 最后是 tbl_ledger_branch 表。但有时列余额值可能为空。例如, 如果4月2日eff_date列的balance值为null,则应从balance中输入 前一天的价值。这个想法是我根据下面的代码将表格与自身连接起来

select
a.ledger_code , a.ref_cur_id , a.ref_branch,a.balance,
b.ledger_code  ,b.ref_cur_id, b.ref_branch ,b.balance

from  (select * from tbl_ledger_input where eff_date = '06-APR-21' ) a  

left join  (select * from tbl_ledger_input where eff_date = '07-APR-21') b

on  a.ledger_code = b.ledger_code  and  

a.ref_cur_id = b.ref_cur_id  and a.ref_branch = b.ref_branch  

where b.ledger_code is null

order by  a.ledger_code , a.ref_cur_id , 
a.ref_branch,b.ledger_code  ,
b.ref_cur_id, b.ref_branch 


enter image description here

,但我只在输出中显示了一天的数据,现在我想为其中的日子编写一个 for 循环 范围, 谢谢你的帮助,请

select
a.ledger_code , a.ref_cur_id , a.ref_branch,a.balance,
NVL(b.ledger_code , a.ledger_code ) , 
NVL(b.ref_cur_id ,a.ref_cur_id ) , NVL(b.ref_branch ,a.ref_branch ) , 
NVL(b.balance , a.balance )




from  (select * from tbl_ledger_input where eff_date = '06-APR-21' ) a 

 left join  (select * from tbl_ledger_input where eff_date = '07-APR-21') b

on  a.ledger_code = b.ledger_code  and  a.ref_cur_id = b.ref_cur_id  and a.ref_branch = 
b.ref_branch  

where b.ledger_code is null

order by  a.ledger_code , a.ref_cur_id , a.ref_branch,b.ledger_code  ,
b.ref_cur_id, b.ref_branch ;

【问题讨论】:

  • edit问题包括一个minimal reproducible exampleCREATE TABLE表的语句; INSERT 一些示例数据的语句(作为文本,而不是图像);您要实现的逻辑的英文描述(不是代码);您的代码的问题/错误的详细信息;以及该样本数据的预期输出。目前您谈论的是日期范围,但您的图像(不使用图像)不显示任何日期,并且您的代码仅使用硬编码字符串,因此不清楚该范围的来源以及您的预期输出会是什么是。
  • SQL 不使用FOR 循环。您可能想要的是行生成器(分层查询或递归查询)来生成日历,然后可能使用 PARTITIONed OUTER JOINLAG 分析函数,但没有问题的更多细节除了猜测之外几乎不可能做任何事情。
  • 您至少第三次问同样的问题(12),并且每次在 SQL 中都有关于 for 循环的 cmet。您能否结合您对所有先前问题的所有答案,阐明此问题与this one 之间的区别?
  • @astentx 我不被允许编辑

标签: sql oracle


【解决方案1】:

如果您的示例数据如下所示:

--  Sample data:
WITH
    tbl_ledger_input (LEDGER_CODE, EFF_DATE, REF_CUR_ID, REF_BRANCH, BALANCE) AS
        (   Select 8011, To_Date('02.04.2021', 'dd.mm.yyyy'), 4, 5751, 200000.00 From Dual  Union All
            Select 8011, To_Date('03.04.2021', 'dd.mm.yyyy'), 4, 5751, 300000.00 From Dual  Union All
            Select 8011, To_Date('04.04.2021', 'dd.mm.yyyy'), 4, 5751, 400000.00 From Dual  Union All
            Select 8011, To_Date('05.04.2021', 'dd.mm.yyyy'), 4, 5751, null      From Dual  Union All
            Select 8011, To_Date('06.04.2021', 'dd.mm.yyyy'), 4, 5751, 500000.00 From Dual  Union All
            Select 8011, To_Date('07.04.2021', 'dd.mm.yyyy'), 4, 5751, null      From Dual  Union All
            Select 8011, To_Date('08.04.2021', 'dd.mm.yyyy'), 4, 5751, 800000.00 From Dual  Union All
            Select 8011, To_Date('09.04.2021', 'dd.mm.yyyy'), 4, 5751, 900000.00 From Dual
        )

如果要填充 BALANCE 列的空值,则可以使用 [LAG() 或 LEAD()][1] 分析函数分别从上一行或下一行获取值。只需注意 OVER() 部分以获得正确的 Partition By 和 Order by 子句。
它会是这样的:

--  Main SQL
SELECT      t.EFF_DATE, 
            t.LEDGER_CODE, 
            t.REF_CUR_ID, t.REF_BRANCH, 
            t.BALANCE, 
            CASE WHEN t.BALANCE Is Null THEN LAG(t.BALANCE) OVER(Partition By t.LEDGER_CODE Order By t.LEDGER_CODE, t.EFF_DATE) END "PREVIOUS_ROW_BALANCE",
            CASE WHEN t.BALANCE Is Null THEN LEAD(t.BALANCE) OVER(Partition By t.LEDGER_CODE Order By t.LEDGER_CODE, t.EFF_DATE) END "NEXT_ROW_BALANCE"
FROM       tbl_ledger_input t -- ON (Nvl(t.EFF_DATE, d.WRK_DATE) = d.WRK_DATE)
WHERE      t.EFF_DATE Between &DATE_START And &DATE_END
ORDER BY   LEDGER_CODE, EFF_DATE

--  R e s u l t :
EFF_DATE  LEDGER_CODE REF_CUR_ID REF_BRANCH    BALANCE PREVIOUS_ROW_BALANCE NEXT_ROW_BALANCE
--------- ----------- ---------- ---------- ---------- -------------------- ----------------
04-APR-21        8011          4       5751     400000                                       
05-APR-21        8011          4       5751                          400000           500000 
06-APR-21        8011          4       5751     500000                                       
07-APR-21        8011          4       5751                          500000           800000 
08-APR-21        8011          4       5751     800000                                       

结果是作为参数 &DATE_START 和 &DATE_END 输入的 04-apr-21 和 08-apr-21 之间的日期
如果我答对了您的问题,则根本不需要任何连接...
此外,如果您想要填充列 BALANCE(当为空时),那么您可以这样做(带注释):

SELECT      t.EFF_DATE, 
            t.LEDGER_CODE, 
            t.REF_CUR_ID, t.REF_BRANCH, 
            CASE WHEN t.BALANCE Is Null THEN LAG(t.BALANCE) OVER(Partition By t.LEDGER_CODE Order By t.LEDGER_CODE, t.EFF_DATE) ELSE t.BALANCE END "BALANCE",
            CASE WHEN t.BALANCE Is Null THEN 'Value from previous row' END "COMMENT"
FROM       tbl_ledger_input t 
WHERE      t.EFF_DATE Between &DATE_START And &DATE_END
ORDER BY   LEDGER_CODE, EFF_DATE

EFF_DATE  LEDGER_CODE REF_CUR_ID REF_BRANCH    BALANCE COMMENT               
--------- ----------- ---------- ---------- ---------- -----------------------
04-APR-21        8011          4       5751     400000                         
05-APR-21        8011          4       5751     400000 Value from previous row 
06-APR-21        8011          4       5751     500000                         
07-APR-21        8011          4       5751     500000 Value from previous row 
08-APR-21        8011          4       5751     800000                         

结果数据集(两者之一)可用于将数据插入到您的 tbl_ledger_branch 表中...... [1]:https://oracle-base.com/articles/misc/lag-lead-analytic-functions

【讨论】:

  • @d r 非常感谢你可爱的 d r,是的,在你的帮助下我的问题已经解决了。非常感谢亲爱的 :)
猜你喜欢
  • 2021-01-20
  • 1970-01-01
  • 2019-04-14
  • 2019-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多