即使MYSQLi具有有效的SQL和PHP语法,它也不返回任何行

Kei*_*vis 3 php mysql mysqli

我在HeidiSQL中运行的SQL代码一次又一次地运行,但是当我将它克隆到PHP并运行mysqli_query($ db,$ sql)时,它不起作用.

以下PHP/MySQL代码都是有效且完美的.

$sql = "select `ID`,`User` from (
            select * from 
                (SELECT 
                    `ID`,
                    `User`,
                    `BI`,
                    (@cnt:= @cnt + (`BI`/(select SUM(`BI`) from `ax`))) as `Entirety`
                from `ax` as `t`
                    CROSS JOIN (SELECT @cnt := 0) AS var
                order by `BI`
            ) d
            where `Entirety`>(@rnd)
            order by `BI`
        ) as `l`
        cross join (select (@rnd := rand()) as `RandomValue`) as var2
        limit 1;";
Run Code Online (Sandbox Code Playgroud)

然后我运行$ sql

$result = mysqli_query($db,$sql);
$results = mysqli_fetch_array($result);
Run Code Online (Sandbox Code Playgroud)

其中$ db是与MySQL服务器有效且开放的连接.但是当我这样做时,物体的回归

print_r($result);
Run Code Online (Sandbox Code Playgroud)

出来了

mysqli_result Object ( 
    [current_field] => 0 
    [field_count] => 2 
    [lengths] => 
    [num_rows] => 0 
    [type] => 0
)
Run Code Online (Sandbox Code Playgroud)

我不想要这个,而且num_rows应该是'1',因为这是HeidiSQL运行时显示的内容.这是HeidiSQL的图像显示结果:

HeidiSQL的结果

有人有主意吗?

表的COLUMNS axID,UserBI.在SQL中,它创建了两个名为"Entirety"的临时列,它是概率计数器和RandomValue一个名为rand()的列,从0到> 1.

此表中唯一的行的值为(1,1,10).虽然它是10,但它有一个Entirety'1',这意味着它是100%保证被选中.尽管如此,没有选择任何东西.

Tho*_*ten 8

如果你在PHP中将EXPLAIN添加到你的查询中,mysqli会告诉你一个子查询的错误:

Impossible WHERE noticed after reading const tables
Run Code Online (Sandbox Code Playgroud)

const row not found
Run Code Online (Sandbox Code Playgroud)

这可能意味着很多,但在这种情况下,我的赌注是列中的无效值.我相当确定

select (@rnd := rand()) as `RandomValue`
Run Code Online (Sandbox Code Playgroud)

之后执行

where `Entirety`>(@rnd)
Run Code Online (Sandbox Code Playgroud)

因此没有设定.

那么,为什么它适用于您的客户?因为客户端保持连接.因此,它在第一次执行查询时失败,但第二次它在第一次执行时具有@rnd的存储值.您可以通过在@ rnd1中重命名@rnd来测试它并运行一次查询.

所以,解决方案是(正如Matt指出的那样)先设置变量@rnd然后再使用它.

以下是关于子查询中用户定义变量的相关SO问题:

MySQL子查询中的用户变量

来自我的客户:

第一次EXPLAIN:

第一次执行

第二次EXPLAIN:

第二次

希望这可以帮助.