SQL 使用 Cursor 的问题 - 关于进行第一笔交易的案例研究

SQL question using Cursor - case study on taking First Transaction

最近,我正在研究SQL。

我有一个基本但模棱两可的问题如下: 给定一个table A,其中包含交易信息,如交易号(TRX_NO)、客户名称(CUS_NAME)、客户代码(CUS_CODE)和交易时间(TRX_TIME).注意到对于每一笔交易,都会有一个记录。比如Mary在20201024、20201025、20201031去商店,那么这个table.

中就有3条记录

考虑到这一点,如果使用 temp_table 或游标,我如何将所有第一次数据插入另一个 table B?

更具体的例子,如果当前tableA存储了Mary的3条记录,那么tableB应该存储20201024的记录,请问有什么方法可以实现?

我试过使用游标,但似乎不是很好的尝试:

  DECLARE var_VIP   VARCHAR2(20);
        
        CURSOR cur_FIRST IS 
                SELECT A.CUS_CODE 
                FROM TABLEA A
                ORDER BY CUS_CODE, TRX_DATE, TRX_TIME;
                
        --OPEN AND START CURSOR
        BEGIN
        OPEN cur_FIRST;
        LOOP
        FETCH cur_FIRST INTO var_VIP;      
        EXIT WHEN cur_FIRST%NOTFOUND;
              INSERT INTO TABLEB B
              (SELECT* 
              FROM TABLEA A
              ORDER BY TRX_DATE, TRX_TIME);
        END LOOP;
        CLOSE cur_FIRST;

非常感谢您的帮助!!!

我写了一个更短的例子,可以帮助你理解这个概念。

   --create the tables
    CREATE TABLE TABLEA (CUS_CODE INTEGER,
                         TRX_DATE DATE);
    
    
    CREATE TABLE TABLEB (CUS_CODE INTEGER,
                         TRX_DATE DATE);
    
    --insert some values
    insert into TABLEA values (1, SYSDATE);
    insert into TABLEA values (1, SYSDATE+1);
    insert into TABLEA values (1, SYSDATE+2);
    
    insert into TABLEA values (2, SYSDATE);
    insert into TABLEA values (2, SYSDATE+1);
    insert into TABLEA values (3, SYSDATE+2);

程序代码:

  DECLARE
        CURSOR cur_FIRST IS 
                SELECT A.CUS_CODE, min(A.TRX_DATE) as TRX_DATE
                FROM TABLEA A
                GROUP BY CUS_CODE;
         
         var_VIP  cur_FIRST%rowtype;      
        --OPEN AND START CURSOR
    BEGIN
        OPEN cur_FIRST;
        LOOP
          FETCH cur_FIRST INTO var_VIP;      
          EXIT WHEN cur_FIRST%NOTFOUND;
              INSERT INTO TABLEB VALUES (VAR_vip.CUS_CODE, VAR_VIP.TRX_DATE);
        END LOOP;
        CLOSE cur_FIRST;
    END;

并查看结果:

SELECT * FROM TABLEB;

您的光标解决方案有点令人困惑,我知道您可能想做什么,但这只是不必要的。您不需要使用显式游标并逐行获取它们,insert 语句可以使用 select 子句。

您的问题通常可以通过分析函数解决,这样您就可以对每个不同客户的所有行进行排名。顺便说一句,我不知道为什么你会有一个名为 TRX_TIMETRX_DATE 的列,在 Oracle 中你有一个日期数据类型,它存储日期和时间组件。如果我们假设 trx_date 是一个日期并且已经填充了时间信息:

insert into tableb (cus_code, trx_no, trx_date, cus_name)
select cus_code, trx_no, trx_date, cus_name
from (
 select cus_code, trx_no, trx_date, cus_name, row_number() over (partition by cus_code order by trx_date) rn
 from   tablea a
)
where rn = 1

请注意,我也在插入语句中明确列出了我的列,而不依赖于 table 中列的顺序(或者在我不知情的情况下没有添加其他列)。