这是一个打印小于1000的质数的mysql代码,但我无法正确理解它,有人可以解释一下这里发生了什么。
SELECT GROUP_CONCAT(NUMB SEPARATOR '&')
FROM (
SELECT @num:=@num+1 as NUMB FROM
information_schema.tables t1,
information_schema.tables t2,
(SELECT @num:=1) tmp
) tempNum
WHERE NUMB<=1000 AND NOT EXISTS(
SELECT * FROM (
SELECT @nu:=@nu+1 as NUMA FROM
information_schema.tables t1,
information_schema.tables t2,
(SELECT @nu:=1) tmp1
LIMIT 1000
) tatata
WHERE FLOOR(NUMB/NUMA)=(NUMB/NUMA) AND NUMA<NUMB AND NUMA>1
)
答案 0 :(得分:3)
让我们逐步解决这个问题。
information_schema.tables有几行?
select count(*) from information_schema.tables t1
-> 370
information_schema.tables,information_schema.tables有几行?
select count(*) from information_schema.tables t1, information_schema.tables t2
--> 370 * 370 = 136900
什么是:=和tmp?
(SELECT @num:=1) tmp
SELECT @num:=1
表示我们正在初始化变量。 (SELECT @num:=1) tmp
表示我们正在用它做一张桌子。
什么是tempNum表?
SELECT @num:=@num+1 as NUMB
FROM
information_schema.tables t1,
information_schema.tables t2,
(SELECT @num:=1) tmp
这几乎与t1,t2组合相同(〜137K记录)。但是,什么列被拉?该列是我们在tmp表中声明的变量,并在其中添加了1。起始编号将是2,然后是3,然后开始。
为什么要过滤NUMB?
仅关注这一部分:
SELECT GROUP_CONCAT(NUMB SEPARATOR '&')
FROM (
SELECT @num:=@num+1 as NUMB FROM
information_schema.tables t1,
information_schema.tables t2,
(SELECT @num:=1) tmp
) tempNum
WHERE NUMB<=1000
这将仅从约23.7到1000结束的约137K记录中获取前1000条记录。GROUP_CONCAT
生成结果2&3&4&5...&1000
。
Tatata做什么?
现在就专注于此。
SELECT * FROM (
SELECT @nu:=@nu+1 as NUMA
FROM
information_schema.tables t1,
information_schema.tables t2,
(SELECT @nu:=1) tmp1
LIMIT 1000
) tatata
此行为与tempNum相似,但略有不同。内部查询从2中选择数字并接受1000个项目。也就是说,最后一个数字是1001。所有这些数字在tatata
虚拟表中都是别名。
结束游戏
关注此部分:
AND NOT EXISTS(
SELECT * FROM (
SELECT @nu:=@nu+1 as NUMA FROM
information_schema.tables t1,
information_schema.tables t2,
(SELECT @nu:=1) tmp1
LIMIT 1000
) tatata
WHERE FLOOR(NUMB/NUMA)=(NUMB/NUMA) AND NUMA<NUMB AND NUMA>1
)
因此,您知道tempNum具有2..1000。上面的查询说,只要tatata的数字不能完全除以tempNum,就可以从tempNum中获取所有内容。
下一个号码
下一个号码
然后...
如您所见,素数是从tempNum中提取的。 GROUP_CONCAT
只是获取结果质数,并将它们与&
相连,从而得到2&3&5&7...