2015-09-06 1 views
1

Я пытаюсь удалить повторяющиеся записи в таблице, но если они дублируются для записи из другой.SQL-удаление записей с группой по нескольким таблицам

Следующий запрос дает мне количество дубликатов записей на «bodyshop». Im пытается удалить несколько счетов-фактур для каждого bodyshop.

SELECT 
    inv.InvoiceNo, job.BodyshopId, COUNT(*) 
FROM 
    [Test].[dbo].[Invoices] as inv 
    join [Test].[dbo].Repairs as rep on rep.Id = inv.RepairId 
    join [Test].[dbo].Jobs as job on job.Id = rep.JobsId 
GROUP BY 
    inv.InvoiceNo, job.BodyshopId 
HAVING 
    COUNT(*) > 1 

Я хочу дублированные номера счетов-фактур на техцентр быть удалены, но я хочу сделать оригинальную один остаться.

InvoiceNo BodyshopId (No column name) 
29737  16   2 
29987  16   3 
30059  16   2 
23491  139   2 
23608  139   3 
23867  139   4 
23952  139   3 

Я хочу только номер счета 29737 быть один раз против bodyshopid 16 и т.д.

Надежда, что имеет смысл

Благодаря

+1

Как вы знаете, какая строка является «оригинальный» Посмотрите на 'ROW_NUMBER() OVER РАЗДЕЛА BY..' – Mihai

+0

Вы не очень, но сейчас это не имеет значения. В таблице счетов есть созданное по дате поле, которое мы могли бы использовать, чтобы сказать, что последнее или самое старое является оригинальным, но не суетится, поскольку значения одинаковы в записях. – Beginner

+0

@Beginner: Я думаю, что min ('InvoiceNo') может быть оригиналом? – Riad

ответ

0

Возможно, это:

with cte as (
SELECT 
    inv.ID, inv.InvoiceNo, job.BodyshopId, rn = row_number() over (partition by inv.InvoiceNo, job.BodyshopId order by inv.InvoiceNo, job.BodyshopId) 
FROM 
    [Test].[dbo].[Invoices] as inv 
    join [Test].[dbo].Repairs as rep on rep.Id = inv.RepairId 
    join [Test].[dbo].Jobs as job on job.Id = rep.JobsId 
) 

delete t1 
from [Test].[dbo].[Invoices] t1 inner join cte t2 on t1.ID = t2.ID 
where t2.rn > 1 

Edit 1 - Ваши комментарии истины. Таким образом, решение состоит в том, чтобы добавить столбец идентификатора в таблицу счетов. Я адаптирую свой запрос.

Чтобы добавить/удалить столбец идентификаторов:

alter table [Test].[dbo].[Invoices] id int identity(1,1) 
drop column id 
+1

Просмотр или функция 'cte' не обновляется, потому что модификация затрагивает несколько базовых таблиц. - Получаю это сообщение – Beginner

+1

и это не удалит все дубликаты счетов? теперь живет хотя бы один? – Beginner

+0

@Beginner Я попытался улучшить свой ответ. – Polux2

0

Вы можете запустить следующие, как две записи же так, Group by будет возвращать одну строку для того же счета-фактуры:

DELETE FROM inv where id not in (
SELECT Max(inv.id) FROM (
SELECT 
    inv.id, inv.InvoiceNo, job.BodyshopId, COUNT(*) 
FROM 
    [Test].[dbo].[Invoices] as inv 
    join [Test].[dbo].Repairs as rep on rep.Id = inv.RepairId 
    join [Test].[dbo].Jobs as job on job.Id = rep.JobsId 
GROUP BY 
    inv.InvoiceNo, job.BodyshopId 
HAVING 
    COUNT(*) > 1 
) TMP_TABLE) 

ID является основным ключом.

Генеральный SQL. Измените, если необходимо, для sql-сервера.

+0

. Не будет ли это удалять все остальные счета в таблице, у которых нет дубликатов? – Beginner

+0

Действительно, я думаю, мы должны сгруппировать, а затем выбрать максимальный идентификатор счета, а затем удалить его, а затем повторить снова, чтобы удалить один дубликат за раз. Если счет-фактура не имеет дубликата, он не будет отображаться в инструкции, поэтому не удаляется. – Beginner