[英]Union select with variable, in PHP with PDO. How to do it right?
I am trying to run a query that returns a random row, and 2 rows surrounding that row (previous and next). 我试图运行一个查询,该查询返回一个随机行,以及围绕该行的2行(上一个和下一个)。
I have saved the random result value in a variable so it can be used by all the following queries. 我已经将随机结果值保存在变量中,以便随后的所有查询都可以使用它。
My query is as follows: 我的查询如下:
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);
the @rand does contain a valid random ID. @rand确实包含有效的随机ID。
It turns out to have been a display issue on the phpmyadmin interface I had been using from a university pc. 原来,这是我在大学电脑上使用的phpmyadmin界面上的显示问题。
The query executes correctly and in the mysql command line interface the rows are shown correctly. 查询正确执行,并且在mysql命令行界面中,行正确显示。 However in PHP/pdo it now returns 但是在PHP / pdo中,它现在返回
PDOStatement::fetchAll(): SQLSTATE[HY000]: General error
whereas the same code without @rand in the query and using a static id for testing purposes, it returns the 3 rows as expected. 而在查询中没有@rand且使用静态ID进行测试的相同代码,它会按预期返回3行。
You have set that query such that it will return at max 3 rows as you have used LIMIT 1
for each 3 queries. 您已经设置了该查询,以使它最多返回3行,因为您对每3个查询使用了LIMIT 1
。
The other thing, despite this, you have also applied filtering to these query using 除此之外,您还使用以下方法对这些查询应用了过滤
where id > @rand
So, how can you expect more than 3 rows ? 那么,您如何期望超过3行?
May be to get previous & next row, you can use this logic as, 可能是获得上一行和下一行,您可以使用以下逻辑,
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
Will work little bit better. 会更好一点。
You can get your result by this way 这样可以得到结果
SELECT *
FROM `data`
where `id` between @rand-1 and @rand+
Ok. 好。 Then you can try this 那你可以试试看
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
I suspect that PDO is having trouble running two SQL statements. 我怀疑PDO在运行两个SQL语句时遇到问题。 I would create a stored procedure to run the statements and use PDO to call the stored proc: 我将创建一个存储过程来运行语句并使用PDO调用存储过程:
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;
Then call it like this: 然后这样称呼它:
$stmt = $dbh->prepare("CALL spGetThreeRandomRows()");
$stmt->execute();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.