2010-08-24 3 views
0

Только для MSSQL 2000-2005 по SQL запросов и хранимых процедур неУдалить дубликаты - SQL сервер 2000-2005

Нет курсоры и временных таблиц

Таблица

create table my_table 
(
row_id int identity(1,1), 
_key varchar(20), 
_total decimal(18,2) 
) 

Вставьте данные

insert into my_table (_key,_total) Values('qwe',10) 
insert into my_table(_key,_total) Values ('qwe',10) 
insert into my_table(_key,_total) Values ('asd',10) 
insert into my_table(_key,_total) Values('asd',10) 
insert into my_table(_key,_total) Values('zxc',10) 
insert into my_table(_key,_total) Values('zxc',10) 
insert into my_table(_key,_total) Values('qwe',100) 
insert into my_table(_key,_total) Values('qwe',100) 
insert into my_table(_key,_total) Values('asd',100) 
insert into my_table(_key,_total) Values('asd',100) 
insert into my_table(_key,_total) Values('zxc',100) 
insert into my_table(_key,_total) Values('zxc',100) 
insert into my_table(_key,_total) Values('qwe',50) 
insert into my_table(_key,_total) Values('qwe',50) 
insert into my_table(_key,_total) Values('asd',50) 
insert into my_table(_key,_total) Values('asd',50) 
insert into my_table(_key,_total) Values('zxc',50) 
insert into my_table(_key,_total) Values('zxc',50) 

Мне нужно удалить дубликаты по полю _key и оставить строки с максимальным _total и среди них максимум row_id.

мне нужно, чтобы получить этот результат установлен

8 qwe 100.00 
10 asd 100.00 
12 zxc 100.00 
+0

SQL Server 2000 или 2005 ? Это может иметь огромное значение для решения – gbn

ответ

2

чтобы удалить их, что это то, что я понял, «удалить DUP licates»означает:

DELETE FROM dbo.my_table 
WHERE NOT EXISTS(SELECT NULL      
        FROM dbo.my_table x 
        JOIN (SELECT _key, 
            MAX(_total) AS max_total 
          FROM dbo.my_table 
         GROUP BY _key) y ON y._key = x._key 
             AND y.max_total = x._total 
        WHERE x._key = my_table._key 
        AND x._total = my_table._total 
       GROUP BY x._key, x._total 
        HAVING MAX(x.row_id) = my_table.row_id) 

запрос, чтобы выбрать строки, список:

SELECT MAX(x.row_id), 
     x._key, 
     x._total 
    FROM dbo.my_table x 
    JOIN (SELECT _key, 
       MAX(_total) AS max_total 
      FROM dbo.my_table 
     GROUP BY _key) y ON y._key = x._key 
         AND y.max_total = x._total 
GROUP BY x._key, x._total 
+0

@Grienders: Рад видеть, что я тебя правильно понял. –

1

Если вы первый выразить то, что вы хотите, на простом языке, становится легче

  • найти максимальное ROW_ID за (макс общее за ключ)

... который становится ...

  • найти максимальную сумму за ключ
  • присоединиться СПИНКИ найти максимальную ROW_ID за (ключ, макс (всего)) комбинации

Я не запускать это ... Я оставлю это для вас найти недостающие запятые и т.д.

SELECT 
    MAX(row_id) AS MaxRowid, M._key, M._total 
FROM 
    (
    SELECT 
     _key, max(_total) AS TTotal 
    FROM 
     my_table 
    GROUP BY 
     _key 
    ) foo 
    JOIN 
    my_table M ON foo._key = M._key AND foo.TTotal = M._total 
GROUP BY 
    M._key, M._total 

для SQL Server 2005+ я мог бы использовать КТР для различных

;WITH cFoo AS 
(
    SELECT 
     row_id, _key, _total, 
     ROW_NUMBER() OVER (PARTITION BY _key ORDER BY _total DESC, row_id DESC) AS bar 
) 
SELECT 
    row_id, _key, _total 
FROM 
    cFoo 
WHERE 
    bar = 1 
+0

Супер! Это очень хорошо! –

+0

Я забыл одно - мне нужно УДАЛИТЬ дубликаты по полю _key и оставить строки с максимальным _total и среди них максимум row_id. Как удалить эти строки? –

0

Вы могли бы добиться этого с помощью двух запросов:

--Delete all lesser total duplicates 
delete T1 
from My_Table T1, My_Table T2 
where T1._key = T2._key 
and T1._total < T2._total 

--Delete all equal total with lesser row_id duplicates 
delete T1 
from My_Table T1, My_Table T2 
where T1._key = T2._key 
and T1.row_id < T2.row_id