I've included a DB-fiddle, and you can adjust the input parameter accordingly。这返回了我期望的结果,并且与我在PDO中看到的结果不同。
我有以下缩小的表格视图和查询:
CREATE TABLE `tagged` {
`tag` SMALLINT(5) UNSIGNED NOT NULL
}
表具有各种值,但是您可以在数据库中使用1-10作为标记:
INSERT INTO tagged (tag) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)
查询:
SELECT tagged.tag,
(@t := :tag),
@t AS temp_var,
(@t IS NULL OR FIND_IN_SET(tagged.tag, @t) > 0) AS is_match
FROM tagged
HAVING is_match = 1
LIMIT 150
在客户端,命令行,jdbc等中运行时,这似乎很好。如果输入''
或NULL
,我会得到所有结果。类似地,输入'1'
仅产生1
的标签,而输入'1,4'
将检索具有1或4的所有标签。
查询限制这些结果的方式是通过is_match = 1
子句中的HAVING
。当使用PDO运行时,该参数似乎可以正确绑定,但是它会完全忽略子句中的条件:
Array
(
[0] => stdClass Object
(
[tag] => 3
[(@t := ?)] => 1,4
[temp_var] => 1,4
[is_match] => 0 ## this should not have been returned
)
[1] => stdClass Object
(
[tag] => 4
[(@t := ?)] => 1,4
[temp_var] => 1,4
[is_match] => 1
)
用于运行此代码的PHP代码(简化):
$conn = /* pdo connection object */;
$stmt = $conn->prepare(DB::queryOf('test')); //uses our above query from a file
$stmt->bindValue(':tag', $args['tag'], PDO::PARAM_STR); //hardcode binding '1,4'
$stmt->execute(); //also tried plain #execute($args)
return $stmt->fetchAll(PDO::FETCH_OBJ);
有什么我想念的吗?我正在绑定直接字符串参数,并且似乎临时变量在那里并已正确设置。为什么PDO返回其中is_match
= 0
的元素的结果?
答案 0 :(得分:2)
我相信这种行为取决于所使用的RDBMS。
在缺少GROUP BY
子句的情况下,似乎在某些情况下,可以将整个结果视为“一个组”。因为结果中的一行满足HAVING
条件,所以所有都必须通过。
其他阅读内容:
Use of HAVING without GROUP BY in SQL queries
p.s。我认为> 0
不是必需的。
我想我会这样写你的查询:
SELECT tag,
@t := '1,4' AS temp_var,
1 AS is_match
FROM tagged
WHERE @t IS NULL OR FIND_IN_SET(tag, @t)
LIMIT 150;