Oracle 使用游标的SQL问题-获取第一个事务的案例研究

Oracle 使用游标的SQL问题-获取第一个事务的案例研究,oracle,plsql,cursor,Oracle,Plsql,Cursor,最近,我正在研究SQL 我有一个基本但不明确的问题如下: 给定一个表a,其中包括交易信息,如交易编号(TRX_NO)、客户名称(CUS_Name)、客户代码(CUS_Code)和交易时间(TRX_time)。注意,对于每一笔交易,都会有一个记录。例如,当Mary在20201024、20201025、20201031去商店时,该表中保存了三条记录 考虑到这一点,如果使用temp_表或游标,如何将所有首次数据插入另一个表B 更具体的例子是,如果当前表A存储了Mary的三条记录,那么表B应该保存202

最近,我正在研究SQL

我有一个基本但不明确的问题如下: 给定一个表a,其中包括交易信息,如交易编号(TRX_NO)、客户名称(CUS_Name)、客户代码(CUS_Code)和交易时间(TRX_time)。注意,对于每一笔交易,都会有一个记录。例如,当Mary在20201024、20201025、20201031去商店时,该表中保存了三条记录

考虑到这一点,如果使用temp_表或游标,如何将所有首次数据插入另一个表B

更具体的例子是,如果当前表A存储了Mary的三条记录,那么表B应该保存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;

我写了一个简短的例子,这将帮助你理解这个概念

   --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_TIME
的列以及
TRX_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

请注意,我也在insert语句中显式列出了我的列,并且不依赖于表中列的顺序(或者在我不知道的情况下没有添加其他列)。

您的游标解决方案有点混乱,我可以看到您可能在尝试做什么,但这只是不必要的。您不需要使用显式游标并逐行获取它们,
insert
语句可以使用
select
子句

您的问题通常通过分析函数来解决,这样您就可以为每个不同的客户对所有行进行排序。顺便说一句,我不知道为什么会有一个名为
TRX_TIME
的列以及
TRX_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

请注意,我也在insert语句中显式列出了我的列,并且不依赖表中列的顺序(或者在我不知道的情况下没有添加其他列)。

您的DBMS是Oracle还是SQL Server?语法表明是第二个。@BarbarosÖzhan哦,对不起,我没认出它。我正在使用PL/SQL developer PL/SQL developer连接到MySQL?您删除了标记oracle,但没有标记相关的DBMS。@BarbarosÖzhan哦,我明白了。我对SQL世界是如此陌生。。。然而,感谢所有提醒和分享您的知识您的数据库管理系统是Oracle还是SQL Server?语法表明是第二个。@BarbarosÖzhan哦,对不起,我没认出它。我正在使用PL/SQL developer PL/SQL developer连接到MySQL?您删除了标记oracle,但没有标记相关的DBMS。@BarbarosÖzhan哦,我明白了。我对SQL世界是如此陌生。。。然而,感谢所有提醒和分享你的知识,非常感谢你的回答。关于%rowtype,我有点困惑。对不起,请您解释一下您希望通过%rowtype实现什么。谢谢!查看这个有用的链接:……非常感谢您的回答。关于%rowtype,我有点困惑。对不起,请您解释一下您希望通过%rowtype实现什么。谢谢!检查此有用的链接:……感谢Andrew提供有关rownumber()的信息。我以前从未听说过。至于日期和时间,实际上,我想在oracle中创建一个字符串存储而不是日期,所以我有了它们。非常感谢您的解决方案!感谢Andrew提供有关rownumber()的信息。我以前从未听说过。至于日期和时间,实际上,我想在oracle中创建一个字符串存储而不是日期,所以我有了它们。非常感谢您的解决方案!