我正在尝试运行一个返回随机行的查询,并且该行周围有两行(上一行和下一行)。
我已将随机结果值保存在变量中,以便所有以下查询都可以使用它。
我的查询如下:
SET @rand := (SELECT CEIL(RAND() * MAX(id)) FROM data);
(SELECT * FROM `data` where `id` < @rand AND safe = 1 ORDER BY ID DESC LIMIT 1) UNION
(SELECT * FROM `data` where `id` = @rand AND safe = 1 ORDER BY ID DESC LIMIT 1) UNION
(SELECT * FROM `data` where `id` > @rand AND safe = 1 ORDER BY ID ASC LIMIT 1);
@rand确实包含有效的随机ID。
事实证明,这是我在大学电脑上使用的phpmyadmin界面上的显示问题。
查询正确执行,并在mysql命令行界面中正确显示行。但是在PHP / pdo中它现在返回
PDOStatement::fetchAll(): SQLSTATE[HY000]: General error
而在查询中没有@rand且使用静态id进行测试的相同代码,它会按预期返回3行。
答案 0 :(得分:0)
您已设置该查询,使其最多返回3行,因为您为每3次查询使用了LIMIT 1
。
另一方面,尽管如此,您还使用
对这些查询应用了过滤where id > @rand
那么,你怎么能期望超过3行?
可能是以前的&amp;下一行,你可以使用这个逻辑,
SELECT * FROM `data` where `id` < @rand ORDER BY ID DESC LIMIT 1
UNION
SELECT * FROM `data` where `id` = @rand LIMIT 1
UNION
SELECT * FROM `data` where `id` > @rand ORDER BY ID ASC LIMIT 1
会更好一点。
答案 1 :(得分:0)
您可以通过这种方式获得结果
SELECT *
FROM `data`
where `id` between @rand-1 and @rand+
确定。然后你可以试试这个
SET @rand := (SELECT CEIL(RAND() * MAX(id)) FROM data);
SELECT top 1 * FROM `data` where `id` < @rand AND safe = 1 ORDER BY ID DESC
UNION
SELECT top 1 * FROM `data` where `id` = @rand AND safe = 1
UNION
SELECT top 1 * FROM `data` where `id` > @rand AND safe = 1 ORDER BY ID ASC
答案 2 :(得分:0)
我怀疑PDO在运行两个SQL语句时遇到问题。我将创建一个存储过程来运行语句并使用PDO来调用存储的proc:
CREATE PROCEDURE spGetThreeRandomRows()
BEGIN
@rand := (SELECT CEIL(RAND() * MAX(id)) FROM data);
(SELECT * FROM `data` where `id` < @rand AND safe = 1 ORDER BY ID DESC LIMIT 1) UNION
(SELECT * FROM `data` where `id` = @rand AND safe = 1 ORDER BY ID DESC LIMIT 1) UNION
(SELECT * FROM `data` where `id` > @rand AND safe = 1 ORDER BY ID ASC LIMIT 1);
END;
然后这样称呼:
$stmt = $dbh->prepare("CALL spGetThreeRandomRows()");
$stmt->execute();