Reputation: 73
I need your help! I have a table:
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);
i need to make SELECT request which will ignored next or previous duplicated rows and i receive data like this:
- gold:44 (ignored 1 record)
- gold:45
- gold:46
- gold:44 (ignored 2 records)
- gold:47
there is no object which duplicated record will ignore (first,second,last). (i tried to use group by value or distinct but this way removes other records with same value)
Upvotes: 0
Views: 72
Reputation: 5337
Use Select DISTINCT res, value FROM table
... to avoid redundancy
Upvotes: -1
Reputation: 86765
You can solve this with a gaps and islands
solution.
- Normally that involves ROW_NUMBER()
which is not present in MySQL
- The solution below mimics ROW_NUMBER()
with variables and ORDER BY
Link to example : 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)
;
If I add res_ordinal
, val_ordinal
and res_ordinal - val_ordinal
to your data, it can be seen that you can now differentiate between the two sets of 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)
NOTE: According to your data I could use id
instead of making my own res_ordinal
. doing it this way, however, copes with gaps in the id
sequence and having multiple different resources. This means that in the following example the two golds are considered to be duplicates of each other...
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)
Upvotes: 2
Reputation: 73
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
);
works fine
Upvotes: 1
Reputation: 457
Use the DISTINCT clause to select unique rows like so:
SELECT DISTINCT res, value FROM
table
Upvotes: 0