MySQL для получения записей, которые повторяют значение по порядку - PullRequest
3 голосов
/ 06 августа 2009

У меня есть большая таблица с 300 000 записей. Эта таблица имеет целочисленное значение, называемое «скорость», и ее значение составляет от 0 до 100. В первых записях значение равно 0, и я хочу удалить. Я хочу удалить из запроса записи, где поле скорости повторяется более 10 раз. Например:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 5 10 12 13 15 20 30 20 15 10 8 5 2 1 0 0 0 0 4 5 10 20 ...

[------- убрать это -----------] ......................... .............................................. [--- ------] <- не удаляйте это </p>

Спасибо

Ответы [ 3 ]

3 голосов
/ 06 августа 2009

Самый простой способ сделать это с помощью цикла. Вы можете написать хранимую процедуру, которая перебирает записи, или вы можете делать это вне базы данных. Я бы сделал это так, если это нужно сделать один раз. Если это непрерывный процесс, лучше убедиться, что дополнительные данные просто не вставляются в базу данных.

В любом случае, если вы настаиваете на том, чтобы делать это на чистом SQL, без хранимых процедур с циклами, вы можете использовать такой запрос:

set @groupnum=0;

select 
  GroupNum,
  count(*) as RecsInGroup 
from
(
    select 
      t1.id as Id,
      t1.velocity as velocity1,
      t2.velocity as velocity2,  
      if(t1.velocity<>t2.velocity,@groupnum:=@groupnum+1,@groupnum) as GroupNum
    from 
      VelocityTable as t1
    join
      VelocityTable as t2  
    on
      t1.id=t2.id-1
) as groups
group by
  GroupNum  
having RecsInGroup>10

Что здесь происходит?

Шаг 1

Внутренний запрос просто выбирает все записи в вашей таблице, но разбивает данные на последовательные группы.

Итак, используя ваш пример, он делает это:

velocity : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 5 10 12 13 15 20 30 20 15 10  8  5  2  1  0  0  0  0  4  5 10 20
Groupnum : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 18 18 18 19 20 21 22

Он делает это, присоединяя таблицу к себе, связывая последующие записи в таблице. Каждый раз, когда левая и правая скорости различаются, GroupNum увеличивается. В противном случае он остается без изменений.

Шаг 2

Результат, если запрос заключен во внешний запрос и сгруппирован по GroupNum. Опять же, используя ваш пример, вы получите следующее:

GroupNum,RecsInGroup
0,15 // !!
1,1
2,1
3,1
4,1
5,1
6,1
7,1
8,1
9,1
10,1
11,1
12,1
13,1
14,1
15,1
16,1
17,1
18,4 // !!
19,1
20,1
21,1

При добавлении предложения having RecsInGroup>10 результат становится следующим:

GroupNum,RecsInGroup
0,15

Теперь с помощью этого списка GroupNum вы можете удалять записи.

Шаг 3

С запросом выше у вас есть:

  1. Список всех ваших записей с добавленным столбцом GroupNum.
  2. Список групповых номеров, которые необходимо удалить.

На этом этапе удаление записей должно быть простым.

0 голосов
/ 06 августа 2009

большое спасибо. Я почти все, но я попробовал это с MySQL View в качестве источника таблицы, и он не работает (неизвестная таблица ххх). Я не могу использовать всю таблицу, потому что в ней более 19 миллионов записей, мне просто нужна запись за определенный день, номер автомобиля и город.

0 голосов
/ 06 августа 2009

Я бы просто последовательно просматривал записи с окном переменного размера, которое расширяется и сжимается для восприятия идентичных значений. Всякий раз, когда размер>> 10, когда значение изменяется, удалите строки, используя первичные ключи.

Вы можете поместить BEGIN TRAN и COMMIT TRAN в начало и конец операторов DELETE, чтобы сделать вещи достаточно эффективными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...