2012-01-11 2 views
1

У меня есть таблица, состоящая из столбцов id (ключ), символа, направления, диапазона, цены, процента. Я хотел бы удалить данные, в которых символ, направление, цена и процент совпадают с наименьшим диапазоном. Как бы я это сделал?Удаление дубликатов в SQL в Access

Я пытался изменить это утверждение: DELETE FROM aw WHERE id not in (select min(id) from aw group by symbol, direction, price, percent);, чтобы получить что-то на работу.

+0

Непонятно о вашем первом абзаце. Означает ли это, что вы хотите сохранить только одну строку для каждой комбинации символов, направления, цены и процента ...и эта строка должна быть первой с наименьшим значением диапазона для этой комбинации полей? – HansUp

+0

@HansUp, это именно то, что я хочу – Mike

ответ

2

Ниже приведен пример данных для Aw таблицы. На основании вашего описания, я думаю, что вы хотите отказаться от строки с ID значениями 2, 3 и 5.

ID symbol direction range price percent 
1 a  x   15 10  5 
2 a  x   20 10  5 
3 b  y   40 50  5 
4 b  y   10 50  5 
5 a  x   15 10  5 

Определить минимальное значение диапазона для каждой комбинации symbol, direction, price и percent ,

qryMinRanges:

SELECT 
    aw.symbol, 
    aw.direction, 
    aw.price, 
    aw.[percent], 
    Min(aw.range) AS MinOfrange 
FROM aw 
GROUP BY 
    aw.symbol, 
    aw.direction, 
    aw.price, 
    aw.[percent]; 

... который дает этот результирующий набор:

symbol direction price percent MinOfrange 
a  x   10  5   15 
b  y   50  5   10 

Определить минимальный ID для каждого из этих минимальных диапазонов.

qryMinID_forMinRanges:

SELECT 
    q.symbol, 
    q.direction, 
    q.price, 
    q.[percent], 
    q.MinOfrange, 
    Min(aw.ID) AS MinOfID 
FROM 
    qryMinRanges AS q 
    INNER JOIN aw 
    ON 
     (q.MinOfrange = aw.range) 
     AND (q.[percent] = aw.[percent]) 
     AND (q.price = aw.price) 
     AND (q.direction = aw.direction) 
     AND (q.symbol = aw.symbol) 
GROUP BY 
    q.symbol, 
    q.direction, 
    q.price, 
    q.[percent], 
    q.MinOfrange; 

... который дает этот результирующий набор:

symbol direction price percent MinOfrange MinOfID 
a  x   10  5   15  1 
b  y   50  5   10  4 

Так qryMinID_forMinRanges должен представлять строки, которые вы хотите сохранить. В конечном счете вы удалите строки из aw, чьи идентификационные значения не включены в qryMinID_forMinRanges. Но сначала попробуйте этот запрос SELECT, чтобы подтвердить, что вы нацеливаете правильные записи для удаления.

SELECT 
    aw.ID, 
    aw.symbol, 
    aw.direction, 
    aw.range, 
    aw.price, 
    aw.[percent] 
FROM aw 
WHERE aw.ID Not In 
    (SELECT MinOfID FROM qryMinID_forMinRanges); 

... что дает мне этот набор результатов:

ID symbol direction range price percent 
2 a  x   20 10  5 
3 b  y   40 50  5 
5 a  x   15 10  5 

Таким образом, если это выглядит правильно, изменить его на запрос на удаление.

DELETE * 
FROM aw 
WHERE 
    (((aw.ID) Not In 
     (SELECT MinOfID FROM qryMinID_forMinRanges))); 

ДБ двигатель не требует * после удаления. Но если вы хотите использовать предварительный просмотр конструктора запросов, вам нужно предоставить ему полевую спецификацию.

Примите меры предосторожности, чтобы защитить ваши данные на случай, если я привожу любые детали здесь. Резервные копии хороши. :-)

2

Попробуйте использовать пункт exists:

DELETE FROM aw 
WHERE 
    exists (
     select 
      1 
     from 
      (select symbol, direction, price, percent, min(range) as minrange from aw 
      group by symbol, direction, price, percent) aw2 
     where 
      aw2.symbol = aw.symbol 
      and aw2.direction = aw.direction 
      and aw2.price = aw.price 
      and aw2.percent = aw.percent 
      and aw2.minrange = aw.range 
    ) 
+0

, но мне нужен минимальный диапазон, а не min id – Mike

+0

@Mike - Извините, неверно сформулируйте ваш вопрос. Попробуйте это :) – Eric

+0

Я бы не стал просто запускать запрос 'DELETE', как это. Кто знает, что он может сделать, если у него есть ошибка; он может просто удалить все. –

Смежные вопросы