#sql
#sql
Вопрос:
У меня есть таблица, которая содержит серию связанных записей (пакетов). Каждый пакет имеет уникальный идентификатор и может содержать платежи клиентов. Я хочу определить, является ли пакет дублирующимся, даже если он отправлен в разные дни.
Пакет может содержать 1 или более записей. Вот пример набора данных:
BatchId InputAmount CustomerName BatchDate
------- ----------- ------------ ----------
182944 $475.00 Barry Smith 16-Mar-2019
182944 $260.00 John Smith 16-Mar-2019
182944 $265.00 Jane Smith 16-Mar-2019
182944 $400.00 Sara Smith 16-Mar-2019
182944 $175.00 Andy Smith 16-Mar-2019
182945 $475.00 Barry Smith 16-Mar-2019
182945 $260.00 John Smith 16-Mar-2019
182945 $265.00 Jane Smith 16-Mar-2019
182945 $400.00 Sara Smith 16-Mar-2019
182945 $175.00 Andy Smith 16-Mar-2019
183194 $100.00 Paul Green 21-Mar-2019
183195 $100.00 Nancy Green 21-Mar-2019
183197 $150.00 John Brown 20-Mar-2019
183197 $210.00 Sarah Brown 20-Mar-2019
183198 $150.00 John Brown 21-Mar-2019
183198 $210.00 Sarah Brown 21-Mar-2019
183200 $125.00 John Doe 20-Mar-2019
183200 $110.00 Sarah Doe 20-Mar-2019
183202 $125.00 John Doe 21-Mar-2019
183202 $110.00 Sarah Doe 21-Mar-2019
183202 $115.00 Paul Rudd 21-Mar-2019
Пакеты (182944, 182945) и (183197,183198) дублируются, в то время как другие пакеты нет.
Я подумал, может быть, я мог бы создать сводную таблицу с подсчетами и суммами и подобраться ближе, но у меня возникли проблемы с поиском истинных дубликатов, включая также имена.
DECLARE @Summaries TABLE(
BatchId INT,
BatchDate DATETIME,
BatchCount INT,
BatchAmount MONEY)
-- Summarize the Data so we can look for duplicates
INSERT INTO @Summaries
SELECT a.BatchId, a.BatchDate, COUNT(*) AS RecordCount, SUM(a.InputAmount) AS BatchAmount
FROM Batches a
WHERE a.BatchDate BETWEEN '20190316' and '20190321'
GROUP BY a.BatchId, a.BatchDate
ORDER BY a.BatchId DESC
-- find the potential duplicate batches based on the Counts and Sums
SELECT A.* FROM @Summaries A
INNER JOIN (SELECT BatchCount, BatchAmount, BatchDate FROM @Summaries
GROUP BY BatchCount, BatchAmount, BatchDate
HAVING COUNT(*) > 1) B
ON A.BatchCount = B.BatchCount
AND A.BatchAmount = B.BatchAmount
WHERE DATEDIFF(DAY, a.BatchDate, b.BatchDate) BETWEEN -1 AND 1
Спасибо за помощь. Я использую базу данных SQL Server 2012.
Ответ №1:
вы можете попробовать, как показано ниже
with cte as
(select BatchId from table_name
group by BatchId
having count(*)>1
) select * from table_name a where a.BatchId in (select BatchId from cte)
Комментарии:
1. Я не думаю, что это делает то, что я хочу. Дублирующийся пакет будет определяться как два или более идентификатора пакета, которые содержат одинаковое количество записей с одинаковыми суммами для одних и тех же имен клиентов. Похоже, что это просто дает мне дублирующиеся идентификаторы пакетов, что не то, что я хочу. Идентификатор пакета уникален для пакета, но не является уникальным ключом в этой таблице. Это был бы внешний ключ.