有人可以向我解释这个mysql代码

时间:2019-04-27 03:14:46

标签: mysql

这是一个打印小于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
)

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为2
  • 从tatata中获取所有小于2的数字。tatata中没有小于2的数字
  • 因此,该子查询中的信息不存在(NOT EXISTS为真)
  • 提取2

下一个号码

  • tempNum为3
  • 从tatata获得的所有数字都小于3。仅2个即可。
  • 一个接一个地将3除以找到的数字。我们刚刚找到2。因此,将3除以2。这是一个干净的除法吗?不。
  • 因此,该子查询中的信息不存在(NOT EXISTS为真)
  • 提取2

下一个号码

  • tempNum为4
  • 从tatata中获取所有小于4的数字。只有2和3
  • 一个接一个,用找到的数字除以4
  • 2或3是否完全除以4?是的... 2全部除以4。
  • 因此,该子查询中的信息存在。它会返回2(NOT EXISTS为假)
  • 请勿提取4

然后...

如您所见,素数是从tempNum中提取的。 GROUP_CONCAT只是获取结果质数,并将它们与&相连,从而得到2&3&5&7...