【问题标题】:MySQL + Alternative to IN() clause that returns row for each item?MySQL +替代IN()子句返回每个项目的行?
【发布时间】:2018-11-01 11:54:46
【问题描述】:

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

MySQL/PHP/PDO + How to get a row for each (duplicate) entry in IN() clasue?

显然……没有解决办法。 (或者我被告知)..

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

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

$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(任何东西),以便为每个项目返回一行? (这是一个动态发布的数组?)

【问题讨论】:

  • 我不确定你的问题是否有意义; IN 没有做任何事情来“区分”结果。如果有多个行与 IN 列表的元素匹配,则将包括这些行。如果有不同的行,具有不同的值(都在 IN 列表中),那么这些不同的行也将被返回。 ...数据库设计有什么可憎之处使得使用变量作为表名是个好主意?
  • 我认为 topicstarter 的意思是 sqlfiddle.com/#!9/75066f/7,然后他会期望两条记录包含 id 1 brandname a and dosage a,因为他两次使用相同的搜索
  • 啊,我飞过“重复条目”中的重复
  • 正确。表中只有 1 ROW .. 但 IN() 子句中有重复条目。我希望 IN() 子句中的每个项目都有一行。但我的理解是这是不可能的。那么这可以使用 JOIN 或 EXISTS 或其他东西来完成吗?占位符列表和品牌列表由用户从 $_POST[] 中选择动态生成
  • @Raymond Nijland 您的第二个查询按预期返回两行.. 但是我如何在我的查询中使用它?它传入一个动态创建的数组作为要为其返回数据的项目......但也可以用作“订单”(因为在这里保持订单非常重要)

标签: php mysql pdo alternate


【解决方案1】:

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

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 列表,然后加入它。 (这种技术有时也可以用来加快查询速度;因为可以为临时表建立索引以帮助进行连接操作。)

【讨论】:

  • PRETTY 不是这里的要求.. LOL.. 嗯.....我猜不反对。只是不知道该怎么做。
  • 查看编辑以了解解析源列表的最基本方法。不是很漂亮,我的意思是如果你的列表真的很长,你可以更快地开始处理查询长度的问题。
  • 临时表解决方案也将更容易实现并防止使用 PDO 或 MySQLi 进行 SQL 注入
  • @Raymond Nijland 非常感谢您的建议。我只是不太擅长使用我的查询作为基础从示例中将所有内容拼凑在一起。我不清楚我的数组和其他东西去哪里匹配你的硬编码值)我希望仍然有 PDO/参数化保护..etc(不是 SQLi)
  • @whispers 'in item 1' 和 'in item 2' 是您的值的占位符。
猜你喜欢
  • 2016-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-15
  • 2017-01-26
  • 2016-04-26
  • 2018-10-05
  • 2012-07-10
相关资源
最近更新 更多