Я думаю, что ваша проблема - это вариант "проблемы с рюкзаком" .
Я думаю, вы уже понимаете, что вы не можете просто взять то, что ruleIds
соответствует наиболее hashIds
, как предлагают другие ответы, потому что в то время как каждый из этих ruleIds
соответствий говорит 100 hashIds
,все они могут совпадать с одинаковыми 100 hashIds
... но если вы выбрали 10 других ruleIds
, которые соответствуют только 25 hashIds
, но с каждым из hashIds
соответствующие каждому ruleId
уникальности, вы получите более уникальный hashIds
с этим набором.
Чтобы решить эту проблему, вы можете начать с выбора того, что ruleId
соответствует наиболее hashIds
, а затем затем выберите то, что ruleId
соответствует большинству hashIds
, которые не включены в hashIds
, совпадающее с предыдущим ruleIds
... продолжая этот процесс, пока вы не выбрали 10 ruleIds
.
В вашем распределении данных все еще могут быть аномалии, которые приведут к тому, что это не даст оптимального набора ruleIds
... поэтому, если вы хотите сойти с ума, вы можете рассмотреть возможность реализации генетического алгоритма, чтобы попытаться улучшить"фитнес" вашегонабор из 10 ruleIds
.
Это не та задача, которую SQL особенно хорошо подходит для обработки, , но вот пример решения проблемы ранца с помощью генетического алгоритма, написанного на SQL (!)
РЕДАКТИРОВАТЬ
Вот непроверенная реализация решения, где ruleIds
выбирается по 1 за раз, с каждой итерациейвыбор того, что ruleId
имеет самый уникальный hashIds
, который ранее не охватывался другими выбранными ruleIds
:
--------------------------------------------------------------------------
-- Create Test Data
--------------------------------------------------------------------------
create create matches (
id int(10) unsigned not null auto_increment,
hashId int(10) unsigned not null,
ruleId int(10) unsigned not null,
primary key (id)
);
insert into matches (hashid, ruleid)
values
(1,1), (2,1), (3,1), (4,1), (5,1), (6,1), (7,1), (8,1), (9,1), (10,1),
(1,2), (2,2), (3,2), (4,2), (5,2), (6,2), (7,2), (8,2), (9,2), (10,2),
(1,3), (2,3), (3,3), (4,3), (5,3), (6,3), (7,3), (8,3), (9,3), (10,3),
(1,4), (2,4), (3,4), (4,4), (5,4), (6,4), (7,4), (8,4), (9,4), (10,4),
(1,5), (2,5), (3,5), (4,5), (5,5), (6,5), (7,5), (8,5), (9,5), (10,5),
(1,6), (2,6), (3,6), (4,6), (5,6), (6,6), (7,6), (8,6), (9,6), (10,6),
(1,7), (2,7), (3,7), (4,7), (5,7), (6,7), (7,7), (8,7), (9,7), (10,7),
(1,8), (2,8), (3,8), (4,8), (5,8), (6,8), (7,8), (8,8), (9,8), (10,8),
(1,9), (2,9), (3,9), (4,9), (5,9), (6,9), (7,9), (8,9), (9,9), (10,9),
(11,10), (12,10), (13,10), (14,10), (15,10),
(11,11), (12,11), (13,11), (14,11), (15,11),
(16,12), (17,12), (18,12), (19,12), (20,12),
(21,13), (22,13), (23,13), (24,13), (25,13),
(26,14), (27,14), (28,14), (29,14), (30,14),
(31,15), (32,15), (33,15), (34,15), (35,15),
(36,16), (37,16), (38,16), (39,16), (40,16),
(41,17), (42,17), (43,17), (44,17), (45,17),
(46,18), (47,18), (48,18), (49,18), (50,18),
(51,19), (52,19), (53,19), (54,19), (55,19),
(56,20), (57,20), (58,20), (59,20), (60,20)
--------------------------------------------------------------------------
-- End Create Test Data
--------------------------------------------------------------------------
create table selectedRules (
ruleId int(10) unsigned not null
);
set @rulesSelected = 0;
while (@rulesSelected < 10) do
insert into selectedRules (ruleId)
select m.ruleId
from
matches m left join (
select distinct m2.hashId
from
selectedRules sr join
matches m2 on m2.ruleId = sr.ruleId
) prev on prev.hashId = m.hashId
where prev.hashId is null
group by m.ruleId
order by count(distinct m.hashId) desc
limit 1;
set @rulesSelected = @rulesSelected + 1;
end while;
select ruleId from selectedRules;