单表上的MySQL复杂查询问题
在尝试了几种可能性之后,我停了下来。在不让mysql服务器超载数百个查询的情况下,我正试图实现以下目标: 这是桌子单表上的MySQL复杂查询问题,mysql,select,nested,Mysql,Select,Nested,在尝试了几种可能性之后,我停了下来。在不让mysql服务器超载数百个查询的情况下,我正试图实现以下目标: 这是桌子 CREATE TABLE `users` ( `id` int(11) NOT NULL auto_increment, `firstname` varchar(64) NOT NULL, `lastname` varchar(64) NOT NULL, `email` varchar(64) NOT NULL, `status` smallint(5)
CREATE TABLE `users` (
`id` int(11) NOT NULL auto_increment,
`firstname` varchar(64) NOT NULL,
`lastname` varchar(64) NOT NULL,
`email` varchar(64) NOT NULL,
`status` smallint(5) NOT NULL,
`refchid1` int(11) NOT NULL,
`refchid2` int(11) NOT NULL,
`refchid3` int(11) NOT NULL,
`refchid4` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
说明:
(6, 'Lars', 'Luna', 'Morbi.non.sapien@enimgravida.com', 25, 0, 0, 0, 0),
(7, 'Sonya', 'Cox', 'tellus@orci.org', 25, 6, 0, 0, 0),
(8, 'Aiko', 'Hodge', 'vestibulum.neque.sed@vel.edu', 25, 7, 6, 0, 0),
(9, 'Lillith', 'Bray', 'purus.Duis.elementum@necurnasuscipit.org', 25, 8, 7, 6, 0),
(10, 'Macey', 'Hayes', 'mi.pede@aliquetodioEtiam.net', 25, 9, 8, 7, 6);
我试图做到的是:
否则,我建议不要使用status和refchid*列,而只使用一个引用“父”id的refid,然后使用视图生成状态值(关于refid的递归)。我不知道您是如何计算点的,但此查询可能会提供足够的数据,玩它,并在公式运行时将其重写为更新查询
SELECT
parent.*,
SUM(IF(parent.id = child.refchid1, 1, 0)) AS count_ref1,
SUM(IF(parent.id = child.refchid2, 1, 0)) AS count_ref2,
SUM(IF(parent.id = child.refchid3, 1, 0)) AS count_ref3,
SUM(IF(parent.id = child.refchid4, 1, 0)) AS count_ref4,
COUNT(child.id) as count_ref
FROM users AS parent
LEFT JOIN users AS child
ON ( parent.id = child.refchid1
OR parent.id = child.refchid2
OR parent.id = child.refchid3
OR parent.id = child.refchid4)
GROUP BY parent.id
我真的不知道你是如何计算积分的,但是这个查询可能会给你足够的数据,让你在公式运行时使用它,并将它重写为一个更新查询
SELECT
parent.*,
SUM(IF(parent.id = child.refchid1, 1, 0)) AS count_ref1,
SUM(IF(parent.id = child.refchid2, 1, 0)) AS count_ref2,
SUM(IF(parent.id = child.refchid3, 1, 0)) AS count_ref3,
SUM(IF(parent.id = child.refchid4, 1, 0)) AS count_ref4,
COUNT(child.id) as count_ref
FROM users AS parent
LEFT JOIN users AS child
ON ( parent.id = child.refchid1
OR parent.id = child.refchid2
OR parent.id = child.refchid3
OR parent.id = child.refchid4)
GROUP BY parent.id
我应该创建一个用户列表和一个单独的参考表
CREATE TABLE reference
(
reference_id SERIAL,
new_user_id BIGINT UNSIGNED NOT NULL,
refered_user_id BIGINT UNSIGNED NOT NULL,
reference_depth INT UNSIGNED NOT NULL
);
当您添加一个新用户时,如果该用户被另一个用户引用,则添加一行深度为1
INSERT INTO reference SET
new_user_id = $new_user_id,
refered_user_id = $refered_user_id,
reference_depth = 1
然后选择链接到该用户的所有引用,并将深度添加为1:
INSERT INTO reference (new_user_id, refered_user_id, reference_depth)
SELECT $new_user_id, refered_user_id, reference_depth +1
FROM reference WHERE new_user_id = $refered_user_id;
然后计算点
SELECT
SUM(
IF(reference_depth = 1, 10, 0)
+ IF(reference_depth = 2, 3, 0)
+ IF(reference_depth = 3, 2, 0)
+ IF(reference_depth > 3, 1, 0)
)
FROM reference
WHERE new_user_id = $user_id
我应该创建一个用户列表和一个单独的参考表
CREATE TABLE reference
(
reference_id SERIAL,
new_user_id BIGINT UNSIGNED NOT NULL,
refered_user_id BIGINT UNSIGNED NOT NULL,
reference_depth INT UNSIGNED NOT NULL
);
当您添加一个新用户时,如果该用户被另一个用户引用,则添加一行深度为1
INSERT INTO reference SET
new_user_id = $new_user_id,
refered_user_id = $refered_user_id,
reference_depth = 1
然后选择链接到该用户的所有引用,并将深度添加为1:
INSERT INTO reference (new_user_id, refered_user_id, reference_depth)
SELECT $new_user_id, refered_user_id, reference_depth +1
FROM reference WHERE new_user_id = $refered_user_id;
然后计算点
SELECT
SUM(
IF(reference_depth = 1, 10, 0)
+ IF(reference_depth = 2, 3, 0)
+ IF(reference_depth = 3, 2, 0)
+ IF(reference_depth > 3, 1, 0)
)
FROM reference
WHERE new_user_id = $user_id
因此,将其视为一棵树,基本上你的意思是,在任何级别中,每引用10个用户,更高级别的所有用户都会获得1个状态点?这是一个正确的假设。说明:用户A在refchid1上有10个引用,在refchid1上的10个引用中,每个引用都有用户A在他们的refchid2上,他们在refchid1上引用了10个用户。因此,将此视为一个树,基本上你的意思是,在任何级别中,每引用10个用户,所有更高级别的用户都会获得1个状态点?这是一个正确的假设。说明:用户A在refchid1上有10个引用,在refchid1上的10个引用中,每个引用都有用户A在其refchid2上,其中每个引用都在refchid1上引用了10个用户。我以前有过类似的查询。我用40000个条目填充了数据库,仔细地设置了层次结构,这样1-116中的几个用户就可以引用其他人了。使用上面的查询,mysql服务器仍然试图在我写这篇文章时给我一个结果。运行5分钟后。返回结果花费的时间太长:)我让您建议的查询运行了45分钟,仍然没有结果:p表上有哪些键/索引?上面一个查询的描述是什么,它使用键吗?如果你看我的原始帖子,那就是我的表。ID是唯一的键/索引。从您的问题中,我推断您希望我为refchid字段设置更多的键/索引?省略索引,mysql将所有行与所有行匹配,然后对它们进行过滤,如果您为4列添加4个索引,mysql将在合并行之前进行过滤,这将大大减少时间。ALTER TABLE users添加键(refchid1)、添加键(refchid2)、添加键(refchid3)、添加键(refchid4);我以前也有过类似的疑问。我用40000个条目填充了数据库,仔细地设置了层次结构,这样1-116中的几个用户就可以引用其他人了。使用上面的查询,mysql服务器仍然试图在我写这篇文章时给我一个结果。运行5分钟后。返回结果所用的时间太长:)我让您建议的查询运行了45分钟,仍然是