如何使用PLSQL根据一列中的重复值和另一列中的连续值进行筛选?
我有一个数据库表,在一个特定列中包含一些重复的行。我只想显示那些行,但仅当相邻列的每组匹配重复项都有连续的数字时才显示。下图显示: 以下是我到目前为止的想法(以下列名与上图不同,上图是为了避免与已定义的SQL函数冲突): 这对于在如何使用PLSQL根据一列中的重复值和另一列中的连续值进行筛选?,plsql,count,duplicates,Plsql,Count,Duplicates,我有一个数据库表,在一个特定列中包含一些重复的行。我只想显示那些行,但仅当相邻列的每组匹配重复项都有连续的数字时才显示。下图显示: 以下是我到目前为止的想法(以下列名与上图不同,上图是为了避免与已定义的SQL函数冲突): 这对于在amt列中获取副本似乎相当有效 现在,我如何让它只考虑trans\u id列中的连续值?取决于您想如何取回“重复”行,类似的操作可能会起到作用: DECLARE CURSOR c IS SELECT * FROM T ORDER BY AMT,NAME,TRANS
amt
列中获取副本似乎相当有效
现在,我如何让它只考虑trans\u id
列中的连续值?取决于您想如何取回“重复”行,类似的操作可能会起到作用:
DECLARE
CURSOR c IS SELECT * FROM T ORDER BY AMT,NAME,TRANS_ID;
curr_rec c%ROWTYPE;
base_rec c%ROWTYPE;
BEGIN
FOR curr_rec IN c
LOOP
IF curr_rec.AMT = base_rec.AMT AND curr_rec.NAME = base_rec.NAME
THEN
DBMS_OUTPUT.PUT(base_rec.TRANS_ID);
DBMS_OUTPUT.PUT(' ');
DBMS_OUTPUT.PUT_LINE(curr_rec.TRANS_ID);
ELSE
base_rec := curr_rec;
END IF;
END LOOP;
NULL;
END;
这是一个简单的循环,遍历已排序的行,根据条件curr\u rec.AMT=base\u rec.AMT和curr\u rec.NAME=base\u rec.NAME
(或任何您需要的内容,只要它与游标的sorted
子句的前缀相匹配)
给定示例数据,输出为:
8085 8086
8085 8087
8085 8088
PL/SQL并不严格要求查找共享一个属性但在另一个属性上具有连续值的数据 使用您的常规表结构,以下内容将定位任何共享相同业务日期和金额、具有相邻交易ID的交易对 创建并加载表后:
CREATE TABLE MY_TABLE (
BIZ_DATE DATE NOT NULL,
NAME VARCHAR2(200) NOT NULL,
AMT NUMBER NOT NULL,
TRANS_ID NUMBER NOT NULL );
INSERT INTO MY_TABLE
(BIZ_DATE, NAME, TRANS_ID, AMT)
VALUES (TO_DATE('17-MAY-2015', 'DD-MON-YYYY'), 'BOB', 8086, 159);
INSERT INTO MY_TABLE
(BIZ_DATE, NAME, TRANS_ID, AMT)
VALUES (TO_DATE('17-MAY-2015', 'DD-MON-YYYY'), 'BOB', 8085, 159);
INSERT INTO MY_TABLE
(BIZ_DATE, NAME, TRANS_ID, AMT)
VALUES (TO_DATE('17-MAY-2015', 'DD-MON-YYYY'), 'BOB', 9088, 159);
INSERT INTO MY_TABLE
(BIZ_DATE, NAME, TRANS_ID, AMT)
VALUES (TO_DATE('17-MAY-2015', 'DD-MON-YYYY'), 'BOB', 9087, 159);
INSERT INTO MY_TABLE
(BIZ_DATE, NAME, TRANS_ID, AMT)
VALUES (TO_DATE('17-MAY-2015', 'DD-MON-YYYY'), 'BOB', 1111, 159);
INSERT INTO MY_TABLE
(BIZ_DATE, NAME, TRANS_ID, AMT)
VALUES (TO_DATE('17-APR-2015', 'DD-MON-YYYY'),'BOB', 5903, 159);
INSERT INTO MY_TABLE
(BIZ_DATE,NAME, TRANS_ID, AMT)
VALUES (TO_DATE('17-MAR-2015', 'DD-MON-YYYY'),'BOB', 5904, 160);
可以通过分析函数比较相邻值:
SELECT BIZ_DATE, AMT, COUNT(*) FROM MY_TABLE WHERE TRAN_DATE
= '03-APR-2000' GROUP BY AMT, BIZ_DATE, AMT HAVING COUNT(*) > 1;
SELECT
BIZ_DATE,
AMT,
TRANS_ID,
PRIOR_TRANS_ID
FROM
(SELECT
BIZ_DATE,
AMT,
TRANS_ID,
LAG(TRANS_ID, 1, TRANS_ID)
OVER (PARTITION BY BIZ_DATE, AMT
ORDER BY TRANS_ID ASC)
AS PRIOR_TRANS_ID
FROM MY_TABLE
WHERE BIZ_DATE = TO_DATE('17-MAY-2015', 'DD-MON-YYYY'))
WHERE (TRANS_ID - PRIOR_TRANS_ID) = 1;
结果:
BIZ_DATE AMT TRANS_ID PRIOR_TRANS_ID
2015-05-17 159 8086 8085
2015-05-17 159 9088 9087
为什么需要存储过程?呃…快速查找导致问题的重复项,而无需做太多工作。有更好的方法吗?我相信还有其他方法来收集这类数据。我在下面发布了一个非plsql方法。谢谢,我不知道怎么用这个。剧本上说已经完成了。但是没有输出。我实际上不需要在结果中看到Trans_id。我只需要将结果显示为底部图像(期望的结果),但仅由另一列中连续的记录过滤。因此,结果应该与所需的结果表完全相似。(有可能)