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_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
请注意,我也在插入语句中明确列出了我的列,而不依赖于 table 中列的顺序(或者在我不知情的情况下没有添加其他列)。
最近,我正在研究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_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
请注意,我也在插入语句中明确列出了我的列,而不依赖于 table 中列的顺序(或者在我不知情的情况下没有添加其他列)。