如何使用PLSQL根据一列中的重复值和另一列中的连续值进行筛选?

如何使用PLSQL根据一列中的重复值和另一列中的连续值进行筛选?,plsql,count,duplicates,Plsql,Count,Duplicates,我有一个数据库表,在一个特定列中包含一些重复的行。我只想显示那些行,但仅当相邻列的每组匹配重复项都有连续的数字时才显示。下图显示: 以下是我到目前为止的想法(以下列名与上图不同,上图是为了避免与已定义的SQL函数冲突): 这对于在amt列中获取副本似乎相当有效 现在,我如何让它只考虑trans\u id列中的连续值?取决于您想如何取回“重复”行,类似的操作可能会起到作用: DECLARE CURSOR c IS SELECT * FROM T ORDER BY AMT,NAME,TRANS

我有一个数据库表,在一个特定列中包含一些重复的行。我只想显示那些行,但仅当相邻列的每组匹配重复项都有连续的数字时才显示。下图显示:

以下是我到目前为止的想法(以下列名与上图不同,上图是为了避免与已定义的SQL函数冲突):

这对于在
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。我只需要将结果显示为底部图像(期望的结果),但仅由另一列中连续的记录过滤。因此,结果应该与所需的结果表完全相似。(有可能)