2015-08-21 5 views
0

Мне нужна ваша помощь! У меня есть таблица:Как игнорировать следующий дублированный ряд?

CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `res` varchar(255) DEFAULT NULL, 
    `value` int(6) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8; 

-- Records of table 

INSERT INTO `table` VALUES (1, 'gold', 44); 
INSERT INTO `table` VALUES (2, 'gold', 44); 
INSERT INTO `table` VALUES (3, 'gold', 45); 
INSERT INTO `table` VALUES (4, 'gold', 46); 
INSERT INTO `table` VALUES (5, 'gold', 44); 
INSERT INTO `table` VALUES (6, 'gold', 44); 
INSERT INTO `table` VALUES (7, 'gold', 44); 
INSERT INTO `table` VALUES (8, 'gold', 47); 

мне нужно сделать SELECT, запрос, который будет проигнорирован следующий или предыдущий дублированные строки и я получать данные, как это:

- gold:44 (ignored 1 record) 
- gold:45 
- gold:46 
- gold:44 (ignored 2 records) 
- gold:47 

нет ни одного объекта, который дублируется запись будет игнорировать (первый, второй, последний). (я пытался использовать группу по значению или различны, но таким образом удаляет другие записи с одинаковым значением)

+0

Пожалуйста, покажите что вы уже пробовали ... – Shnugo

+0

Я не понимаю, почему вы хотите это сделать? – jarlh

+0

Единственный способ сделать эту работу с помощью переменных MySQL и/или сделать функцию lag() или lead(), как в T-SQL, для проверки следующей и предыдущей строки – DieVeenman

ответ

2

Вы можете решить это с помощью решения gaps and islands.
- Обычно это включает в себя ROW_NUMBER(), который не присутствует в MySQL
- Решение ниже мимике ROW_NUMBER() с переменными и ORDER BY

Ссылка на пример: http://sqlfiddle.com/#!9/32e72/12

SELECT 
    MIN(id) AS id, 
    res, 
    value 
FROM 
(
    SELECT 
     IF (@res = res AND @val = value, @row := @row + 1, @row := 1)  AS val_ordinal, 
     id    AS id, 
     res_ordinal  AS res_ordinal, 
     @res := res  AS res, 
     @val := value AS value 
    FROM 
    (
     SELECT 
      IF (@res = res     , @row := @row + 1, @row := 1)  AS res_ordinal, 
      id    AS id, 
      @res := res  AS res, 
      @val := value AS value 
     FROM 
      `table`, 
     (
      SELECT @row := 0, @res := '', @val := 0 
     ) 
      AS initialiser 
     ORDER BY 
      res, id 
    ) 
     AS sequenced_res_id, 
    (
     SELECT @row := 0, @res := '', @val := 0 
    ) 
     AS initialiser 
    ORDER BY 
     res, value, id 
) 
    AS sequenced_res_val_id 
GROUP BY 
    res, 
    value, 
    res_ordinal - val_ordinal 
ORDER BY 
    MIN(id) 
; 

Если добавить res_ordinal, val_ordinal и res_ordinal - val_ordinal к ваши данные, можно видеть, что теперь вы можете провести различие между двумя наборами 44

               GROUP 

INSERT INTO `table` VALUES ('1', 'gold', '44'); 1 - 1 = 0 (Gold, 44, 0) 
INSERT INTO `table` VALUES ('2', 'gold', '44'); 2 - 2 = 0 

INSERT INTO `table` VALUES ('3', 'gold', '45'); 3 - 1 = 2 (Gold, 45, 2) 

INSERT INTO `table` VALUES ('4', 'gold', '46'); 4 - 1 = 3 (Gold, 46, 3) 

INSERT INTO `table` VALUES ('5', 'gold', '44'); 5 - 3 = 2 (Gold, 44, 2) 
INSERT INTO `table` VALUES ('6', 'gold', '44'); 6 - 4 = 2 
INSERT INTO `table` VALUES ('7', 'gold', '44'); 7 - 5 = 2 

INSERT INTO `table` VALUES ('8', 'gold', '47'); 8 - 1 = 7 (Gold, 47, 7) 

ПРИМЕЧАНИЕ. Согласно вашим данным, я мог бы использовать id вместо того, чтобы создавать свои собственные res_ordinal. тем не менее, он справляется с пробелами в последовательности id и имеет несколько разных ресурсов. Это означает, что в следующем примере две золотые медали считаются дубликатами друг друга ...

1 Gold 44  1 - 1 = 0 (Gold, 44, 0) 
2 Poop 45  1 - 1 = 0 (Poop, 45, 0) 
3 Gold 44  2 - 2 = 0 (Gold, 44, 0) -- Duplicate 
4 Gold 45  3 - 1 = 2 (Gold, 44, 2) 
+0

Он говорит, что MySQL не T-SQL – DieVeenman

+1

@DieVeenman - Обновлено, чтобы использовать логику MySQL для имитации 'ROW_NUMBER()', спасибо за то, что заметили :) – MatBailie

+0

@MatBailie, спасибо вы за свою прекрасную работу! – user3738031

0

Используйте DISTINCT положение, чтобы выбрать уникальные строки так:

SELECT DISTINCT Рез, значение ОТ table

+1

Обратите внимание, что золото: 44 должно быть возвращено дважды. – jarlh

+0

Хм просто сделал, я постараюсь найти ответ – DieVeenman

1
select t1.* 
from `table` t1 
where not exists (select 1 
        from `table` t2 
        where t1.id = 1+t2.id 
        and t1.res = t2.res 
        and t1.value = t2.value 
       ); 

работает отлично

+1

Работы с учетом предположения, что в идентификаторах никогда не было пробелов. Что в реляционной базе данных является опасным предположением; могут быть пробелы из-за вставок других ресурсов, неудачных вставок, удалений и т. д. – MatBailie

-1

Использование Select DISTINCT res, value FROM table ... чтобы избежать избыточности

+0

Это не дает ответа на вопрос. Чтобы критиковать или просить разъяснения у автора, оставьте комментарий ниже их сообщения. – Thom

+0

«Мне нужно сделать запрос SELECT», хорошо, тогда я его неправильно понял – TechTreeDev

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