最近,我正在研究SQL。
我有一个基本但模棱两可的问题如下:给定表a,该表包括交易信息,例如交易编号(TRX_NO(、客户名称(CUS_Name(、客户代码(CUS_Code(和交易时间(TRX_time(。注意,对于每一笔交易,都会有一条记录。例如,当玛丽在20201024、20201025、20201031去商店时,这张表中有三条记录。
考虑到这一点,如果使用temp_table或cursor,我如何将所有首次数据插入另一个表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;
您的游标解决方案有点令人困惑,我可以看到您可能想做什么,但这是不必要的。您不需要使用显式游标并逐行获取它们,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语句中显式列出我的列,而不依赖于表中列的顺序(或者在我不知道的情况下没有添加其他列(。