Я пишу страницу регистрации исключений, используя MySQL для перехвата повторяющихся записей выставления счетов по следующему сценарию.
Детали позиций заносятся в таблицу, которая имеет следующие два столбца (среди прочих).
ItemCode VARCHAR(50), BillEntryDate DATE
Часто бывает, что один и тот же товарный счет вводится несколько раз, но в течение нескольких дней. Подобно,
"Football","2019-01-02"
"Basketball","2019-01-02"
...
...
"Football","2019-01-05"
"Rugby","2019-01-05"
...
"Handball","2019-01-05"
"Rugby","2019-01-07"
"Rugby","2019-01-10"
В приведенном выше примере пункт "Футбол" выставляется дважды - сначала на 2 января, а затем на 5 января. Точно так же, пункт регби выставляется трижды на 5,7,10 января.
Я ищу написать простой SQL, который может забрать каждый элемент [скажем, с использованием отдельного предложения (ItemCode)], а затем отобразить все записи, которые являются дубликатами в течение 30 дней. В вышеприведенном случае ожидаемый результат должен быть следующими 5 записями:
"Football","2019-01-02"
"Football","2019-01-05"
"Rugby","2019-01-05"
"Rugby","2019-01-07"
"Rugby","2019-01-10"
Я пытаюсь запустить следующий SQL:
select * from tablen a, tablen b, where a.ItemCode=b.ItemCode and a.BillEntryDate = b.BillEntryDate+30;
Тем не менее, это кажется крайне неэффективным, так как работает долго без отображения каких-либо записей. Есть ли возможность получить менее сложный и быстрый метод?
Я изучил существующие темы (например, Как найти дубликаты в нескольких столбцах?), Но он ловит дубликаты, где ОБА столбцы имеют одинаковое значение. Мое требование - один столбец с одним и тем же значением, а второй столбец изменяется в диапазоне дат за месяц.
Ты можешь использовать:
select t.*
from tablen t
where exists (select 1
from tablen t2
where t2.ItemCode = t.ItemCode and
t2.BillEntryDate <> t.BillEntryDate and
t2.BillEntryDate >= t1.BillEntryDate - interval 30 day and t2.BillEntryDate <= t1.BillEntryDate + interval 30 day
);
Это подберет оба дубликата в паре.
Для производительности вам нужен индекс (ItemCode, BillEntryDate)
.
С EXISTS
:
select ItemCode, BillEntryDate
from tablename t
where exists (
select 1 from tablename
where
ItemCode = t.ItemCode
and
abs(datediff(BillEntryDate, t.BillEntryDate)) between 1 and 30
)