如何忽略下一个重复的行?

时间:2015-08-21 09:44:10

标签: mysql sql

我需要你的帮助! 我有一张桌子:

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

没有重复记录会忽略的对象(第一个,第二个,最后一个)。 (我尝试使用group by value或distinct,但这样可以删除具有相同值的其他记录)

4 个答案:

答案 0 :(得分:2)

您可以使用gaps and islands解决方案解决此问题 - 通常涉及MySQL中不存在的ROW_NUMBER() - 下面的解决方案使用变量和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_ordinalval_ordinalres_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)

答案 1 :(得分: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
                 );

工作正常

答案 2 :(得分:0)

使用DISTINCT子句选择如下所示的唯一行:

  

SELECT DISTINCT res,value FROM table

答案 3 :(得分:-1)

使用Select DISTINCT res, value FROM table ...以避免冗余