2015-05-16 4 views
1

У меня есть таблица базы данных, которая содержит несколько повторяющихся строк в одном конкретном столбце. Я бы хотел показать только эти строки, но ТОЛЬКО, когда соседний столбец имеет последовательные номера для каждого набора совпадающих дубликатов. На рисунке ниже показано:Как фильтровать на основе повторяющихся значений в одном столбце и последовательных значениях в другом, используя PLSQL?

Filter for Duplicates

Вот что я придумал до сих пор (имена столбцов ниже отличаются от картины, над которой было сделано, чтобы избежать конфликта с определенными функциями SQL):

SELECT BIZ_DATE, AMT, COUNT(*) FROM MY_TABLE WHERE TRAN_DATE 
= '03-APR-2000' GROUP BY AMT, BIZ_DATE, AMT HAVING COUNT(*) > 1; 

Это похоже на работу достаточно хорошо для получения обмана в столбце amt.

Теперь, как мне заставить его учитывать только последовательные значения в столбце trans_id?

+0

Почему вы хотите хранимую процедуру? –

+0

Erm ... чтобы быстро найти дубликаты, которые вызывают проблемы, без особых усилий. Есть лучший способ сделать это? – user2544542

+0

Я считаю, что есть другие способы сбора таких данных. Я разместил ниже подход, отличный от plsql. Спасибо – alexgibbs

ответ

1

PL/SQL не является обязательным условием для поиска данных, разделяющих один атрибут, но имеющих последовательные значения для другого атрибута.

Используя общую структуру таблицы, мы найдем любую пару транзакций, совместно использующую те же BIZ_DATE и AMT, с соседними идентификаторами TRANS_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, 
    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 
0

В зависимости как вы хотите получить обратно свой «дублировать» строк, что-то как что может сделать трюк:

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_rec.AMT = base_rec.AMT AND curr_rec.NAME = base_rec.NAME (или то, что вам нужно, до тех пор, как она совпадает с префикс из SORTED пункта курсора мыши)

Учитывая ваши данные выборки, выход is:

8085 8086 
8085 8087 
8085 8088 
+0

Не уверен, что я знаю, как это использовать. Сценарий только что сказал, что он был закончен. Однако нет выхода. Мне действительно не нужно видеть Trans_id в результатах. Мне просто нужно, чтобы результаты отображались как нижнее изображение (желаемый результат), а FILTERED - только те записи, которые последовательно в другом столбце. Таким образом, результаты должны точно соответствовать желаемой таблице результатов. (возможно) – user2544542

Смежные вопросы