SQL за изтриване на дублиращи се записи с някои общи стойности на полето?

Помислете за таблица със следната схема:

id, location, starred

Има много записи с едно и също местоположение:

id | location | starred
-----------------------
1     rome      yes
2     rome      no
3     rome      no
4     milan     yes
5     milan     no
6     bozen     no

Искам да имам най-много един запис на местоположение. И имайки предвид избора между запис със звезда и запис без звезда, аз искам запис със звезда. И така, какъв sql ще създаде тази таблица:

id | location | starred
-----------------------
1     rome      yes
4     milan     yes
6     bozen     no

Подозирам, че това може да се направи с някои виртуални таблици или „изгледи“.

DELETE FROM table
GROUP BY location, 

person simpatico    schedule 27.06.2012    source източник
comment
Така че искате да изберете само различни градове в схемата и ако има дубликат, искате този със „означен със звезда“ = да?   -  person vandershraaf    schedule 27.06.2012
comment
Да, може би създаване на материализиран изглед на тази заявка за избор.   -  person simpatico    schedule 27.06.2012


Отговори (4)


Ако [started] може да бъде само да или не, тогава това трябва да работи:

create table data
(
id int identity(1,1),
location varchar(50),
[started] varchar(3)
)

insert into data select 'Rome', 'Yes'
insert into data select 'Rome', 'No'
insert into data select 'Rome', 'No'
insert into data select 'Milan', 'Yes'
insert into data select 'Milan', 'No'
insert into data select 'Bozen', 'No'

WITH locationsRanked (id, location, [started], rank)
AS
(
    select min(Id), location, [started],
    RANK() OVER (PARTITION BY location  ORDER BY location, [started] DESC) AS Rank
    from data
    group by location, [started]
)
select * from locationsRanked where Rank = 1
order by id
person Void Ray    schedule 27.06.2012

Използвайте аналитични функции за изтриване на дубликати. Следващият код генерира базирано на row_number местоположение и сортирано по desc със звезда (така че да е първо)

 delete from mytable2 where id in ( 
select id from
( select  id, location,starred,row_number() over ( partition by location order by location, starred desc) row_num 
  from mytable2
) where row_num >1
)
person Ramesh Manni    schedule 27.06.2012
comment
Това би било специфично за MS SQL Server. Идеалното решение за това обаче. - person Philip Kelley; 27.06.2012

Ако просто искате да извлечете данните, нещо подобно трябва да работи:

select
    [table].*
from
    [table]
    inner join (select 
                    MIN(id) as id, 
                    location 
                from 
                    [table] 
                group by location) as data
        on [table].id = data.id

Очевидно можете също да използвате резултатите от тази (или подобна заявка), за да определите списък с идентификатори за изтриване.

person Dave    schedule 27.06.2012
comment
вие пренебрегвате ограничението със звезда - person simpatico; 27.06.2012

Мисля, че това може да ви помогне:

http://www.w3schools.com/sql/sql_distinct.asp

person Robuust    schedule 27.06.2012