【发布时间】:2018-11-01 09:54:34
【问题描述】:
语言:PHP
数据库:MySQL
我的理解是,如果您在 IN() 子句中有重复条目..它们将被跳过...我需要为 IN() 子句中的每个项目返回/行..无论它们是重复项还是不是。
从阅读中...我相信 [self] JOIN() 是我正在寻找的方法/解决方案..但我不清楚如何在同一张桌子上执行此 JOIN? ..尤其是我已经在下面进行的查询。 (它的工作原理是我需要的......期望不为 IN() 子句中的重复条目返回一行)
但是..我也读过关于 EXISTS() 的文章..也许是更好的方法? (我不是在这里寻找速度。我正在寻找一个可行的解决方案)
我有一个用于显示同一张表的 rextexter 示例..(但是这个查询确实适用于 rextester 但不适用于现实世界或 WAMP..etc)
http://rextester.com/SZRIAN96972
所以我不清楚它是否真的是查询本身? (我读到这将是问题所在,因为在 IN() 子句中会跳过 dups)...因为它在 WAMP 和 REXTESTER 中“有效”...
所以也许它是 PDO 操作的一部分?将数组传递给execute()函数时可能发生了什么?
PDO 片段:
$qMarks = str_repeat('?,', count($brandlist) - 1) . '?'; //create '?' mark placeholders for query, remove last comma and replace with '?'
//preserve IN() order
$displayList_sql = "SELECT * FROM $tablename WHERE CONCAT(brandname, ' ', dosage) IN ($qMarks) ORDER BY FIELD(CONCAT(brandname, ' ', dosage),'". trim(implode("','", $brandlist))."')";
$displayList_stmt = $conn->prepare($displayList_sql);
$displayList_stmt->execute($brandlist);//make note of passing in array as param to execute() call
传入的 $brandList 数组示例:(带有 dups)
Zyflo CR Extended-release tablet 600 mg','Zyflo CR Extended-release tablet 600 mg',' SEE NOTES BELOW'
所以在这一点上.. 我不清楚 IN() 子句是否是问题所在?或者,如果在将数组传递给 execute() 命令时正在做某事? 有什么东西在 IN() 子句中剥离/跳过重复项?我怎样才能避免这种情况?我希望它是某种自联接..但我看到的所有示例都有硬编码值(不可能)..然后位于初始 IN() 子句中的重复条目用于第二个查询或其他内容。 (我很关注,因为我看不出这如何适用于我的情况)
这是一个工作示例的快速转储,我一直在本地 WAMP 安装上运行该示例:(需要您自己的连接包含文件)
require_once('../db_wamp_pdo.php');
$tablename = 'xxx';
//hard coded list for testing
$brandList_og = array('Zyflo CR Extended-release tablet 600 mg','Zyflo CR Extended-release tablet 600 mg',' SEE NOTES BELOW', 'Alvesco HFA 80mcg');
function get_displayList($tablename, $conn, $brandlist){
$rowcount = 0;
if($brandlist != '' && count($brandlist) > 0){
$qMarks = str_repeat('?,', count($brandlist) - 1) . '?'; //create '?' mark placeholders for query, remove last comma and replace with '?'
//$displayList_sql = "SELECT * FROM $tablename WHERE CONCAT(brandname, ' ', dosage) IN('Zyflo CR Extended-release tablet 600 mg','Zyflo CR Extended-release tablet 600 mg',' SEE NOTES BELOW', 'Alvesco HFA 80mcg') ORDER BY FIELD(CONCAT(brandname, ' ', dosage),'Zyflo CR Extended-release tablet 600 mg','Zyflo CR Extended-release tablet 600 mg',' SEE NOTES BELOW', 'Alvesco HFA 80mcg')";
$displayList_sql = "SELECT * FROM $tablename WHERE CONCAT(brandname, ' ', dosage) IN($qMarks) ORDER BY FIELD(CONCAT(brandname, ' ', dosage),'". trim(implode("','", $brandlist))."')";
//$displayList_sql = "SELECT * FROM $tablename WHERE CONCAT(brandname, ' ', dosage) FIND_IN_SET($qMarks) ORDER BY FIELD(CONCAT(brandname, ' ', dosage),'". trim(implode("','", $brandlist))."')";
//$displayList_sql = "SELECT * FROM $tablename WHERE EXISTS(SELECT CONCAT(brandname, ' ', dosage)) ORDER BY FIELD(CONCAT(brandname, ' ', dosage),'". trim(implode("','", $brandlist))."')";
$displayList_stmt = $conn->prepare($displayList_sql);
$displayList_stmt->execute($brandlist);//make note of passing in array as param to execute() call
$displayList_stmt->setFetchMode(PDO::FETCH_ASSOC);
$_displayList = $displayList_stmt->fetchAll(); //returns multi-dimensional array (and correct count)
$colcount = $displayList_stmt->columnCount();
$rowcount = $displayList_stmt->rowCount();
}
if($rowcount <= 0){
//nothing returned
}else{
return $_displayList;
}
}
$my_displayList = get_displayList($tablename, $conn, array_values(array_filter($brandList_og)));//array_filter() added to get count of only non empty indexes
echo 'BRAND LIST: <br>';
echo var_dump($my_displayList);
echo '<br>';
我一直在输出调试文本.. 'array' 很好,直到它从查询中返回..
所以它要么是 IN() 子句(我目前的理论),我需要帮助以某种方式向这个动态查询添加一个自联接?或者(不太可信)将数组传递到 execute() 行时......事情正在被解析/删除?
【问题讨论】:
-
不,
IN()子句不会对行进行分组,因此您将收到与 IN 子句匹配的所有行。您可能需要仔细检查您的数据,或者您可以尝试使用 REGEXP。 -
我没有关注。我的结果不支持您的回答。如果我在传递的 $brandList 数组中有 dup ......它将跳过 dup 并且不为它返回任何内容。 (正如最初的那样)这里的几篇文章实际上声明 IN() 子句中的重复将被跳过/忽略....但是您的说法相反?
-
它背后的逻辑是.. IN() 子句只不过是一个 OR= 语句.. 所以如果它在第一个 OR 上匹配.. 随后的 OR 已经被检查/通过并因此跳过?在这种情况下,REGEXP 会为我做什么?我需要查询为 IN() 子句中的每个项目返回一个 ROW。不管它们是否重复