【发布时间】:2017-12-16 20:39:20
【问题描述】:
简介
我有 3 张桌子:
设置:
id
name
设置项:
set_id
item_id
position
临时设置:
id
我有一个函数可以从Item 表中生成新的随机组合。基本上,总是在成功生成后,我在 Set 表中创建一个新行,获取它的 id 并将所有项目 id 添加到 SetItem 表中。
问题
每次在生成新组合之前,我都会截断 TempSet 表,将新的项目 ID 填充到此表中,并通过与 SetItem 表中的先前组合进行比较来检查相似性百分比。如果新的组合相似度大于等于 30%,我需要阻止这个组合并重新生成新的组合。
相似性意味着 - 在先前生成的组合中存在元素。所以,这个想法是:
如果新生成的集合中超过 3 个元素在某个先前生成的集合上重复,则阻止它并尝试生成另一个组合。
这是生成新组合的函数:
CREATE DEFINER = `root` @`localhost` FUNCTION `gen_uniq_perm_by_kw` (
comboSize INT ( 5 ),
tries INT ( 3 )
) RETURNS text CHARSET utf8 SQL SECURITY INVOKER BEGIN
iterat :
LOOP
DELETE
FROM
`TempSet`;
INSERT INTO `TempSet` ( `id` ) (
SELECT
`i`.`id`
FROM
`Item` AS `i`
ORDER BY
RAND( )
LIMIT comboSize
);
IF
(
SELECT
1
FROM
`SetItem`
GROUP BY
`set_id`
HAVING
sum(
CASE
WHEN EXISTS (
SELECT
id
FROM
`TempSet`
WHERE
`id` = `item_id`
LIMIT 1
) THEN
1 ELSE 0
END
) / count( 1 ) * 100 >= 30
LIMIT 1
) < 1 THEN
RETURN ( SELECT GROUP_CONCAT( id SEPARATOR '-' ) FROM `TempSet` );
END IF;
SET tries := tries - 1;
IF
tries = 0 THEN
RETURN NULL;
END IF;
END LOOP iterat;
END
当我测试它时,即使新生成的组合的元素不存在于任何其他先前生成的组合中,它也会返回 null 作为结果。
我的问题是,我做错了什么?
【问题讨论】:
-
修复您的数据结构,以便每行存储一个项目而不是一个字符串。这是在 SQL 中存储数据的正确方法。
-
@GordonLinoff 我已经有了。它对我有什么帮助?
-
我有单独的表,其中组合元素存储在多对多关系结构中
-
删除此问题并提出另一个问题,描述该数据结构。
-
对于这种情况,最好使用图形数据库,它可以显示存在多少组合具体元素。检查
neo4j。否则开发 2 名工人:generator和validator。Generator将生成组合字符串并设置isValid: 0、isValidated: 0标志。Validator将在isValidated: 0记录上工作,并将检查每一行的每个元素并验证您的条件并设置isValid: 1(如果没问题)和isValidated: 1以防止再次验证它。
标签: mysql sql hash combinations similarity