首页 > 解决方案 > MySQL +替代IN()子句返回每个项目的行?

问题描述

好的..所以我在这里发了一个帖子:

MySQL/PHP/PDO + 如何为 IN() 子句中的每个(重复)条目获取一行?

显然......没有解决方案。(或者我被告知)..

那么是否有使用 IN() 子句的替代解决方案?实际上,它确实为传入的每个项目返回一行......不管它是否重复条目?

我有关于使用(自我)JOIN..甚至可能存在的建议......但我不清楚如何使用这些建议来调整我当前的动态查询?

$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

可以将其更改为使用 JOIN 或 EXISTS(任何东西),以便为每个项目返回一行吗?(这是一个动态发布的数组?)

标签: phpmysqlpdoalternate

解决方案


它不是很漂亮,但是您可以将列表“转换”为子查询,并将其与您要查询的实际表连接起来。

SELECT t.stuff
FROM (SELECT 'in item 1' AS item 
      UNION ALL SELECT 'in item 2' 
      UNION ALL ...
) AS inList
INNER JOIN $tablename AS t ON inList.item = CONCAT(t.brandname, ' ', t.dosage)
ORDER BY ...

我的猜测是可能有一些 php 方法可用于分解/拆分用于填充 IN 列表以创建SELECT ... UNION ALL ...子查询的变量。

最糟糕,最原始的情况(在伪代码中),假设一个简单的逗号分隔列表:

theList = "SELECT " + REPLACE(theList, ',', ' AS item UNION ALL SELECT')


如果查询长度成为问题,另一种选择是创建一个临时表来存储 IN 列表,然后加入它。(这种技术有时也可以用来加快查询速度;因为临时表可以被索引以帮助连接操作。)


推荐阅读