【问题标题】:Mysql Codeigniter Active Record - How do I do a where_in query and return the correct order of results?Mysql Codeigniter Active Record - 如何执行 where_in 查询并返回正确的结果顺序?
【发布时间】:2011-11-18 14:05:56
【问题描述】:

我有一组按特定顺序传递的 ID,需要保留。 我正在从几个左连接查询与每个 ID 相关的数据。 ID 是从搜索中返回的,因此必须保持顺序以使结果有效(否则它会使搜索变得毫无意义)。

我的代码看起来像这样;

$this->db->where_in('id', $array_of_ordered_ids);

例如-

$this->db->where_in('id', array(4,5,2,6));

将按 2、4、5、6 的顺序返回结果。

我希望它保留顺序并返回结果 4,5,2,6。

谢谢,

【问题讨论】:

  • 你需要添加一个 order by 子句来告诉 SQL Server 以什么顺序返回行,in(4,5,2,6) 只会指定返回哪个而不是顺序。
  • 你能举出任何使用 CI 的 activerecord 类的 order_by 函数的例子吗?与 where_in 函数不同,order_by 不接受数组作为第二个参数,并且除了可以对 desc、asc 和 random 进行排序之外,文档并没有说明太多。
  • 我添加了一个答案,展示了如何做到这一点(从数组中创建一个字符串)以及您可以使用哪个 mysql 函数。希望对您有所帮助。

标签: php mysql codeigniter search activerecord


【解决方案1】:

要按数组中的顺序对结果进行排序,您可以执行以下操作:

$array_of_ordered_ids = array(4,5,2,6);

由于你已经知道数字的顺序,你可以使用Mysql的FIELD()Docs函数:

ORDER BY FIELD(id, 4, 5, 2, 6);

要创建这样的字符串,可以使用implodeDocs

$order = sprintf('FIELD(id, %s)', implode(', ', $array_of_ordered_ids));

试一试:

$array_of_ordered_ids = array(4,5,2,6);
$this->db->where_in('id', $array_of_ordered_ids);
$order = sprintf('FIELD(id, %s)', implode(', ', $array_of_ordered_ids));
$this->db->order_by($order); 

【讨论】:

  • 谢谢,理论上答案应该是正确的,但感谢您的建议,它帮助我查明了实际问题。作为参考,出了问题的是 codeigniter order_by 用反引号包围了每个输入。因此,任何对 ID 的引用都会被解释为列名!看来我得自己写SQL了。谢谢哈克雷。
  • 也许有另一个参数阻止 CI 这样做,一些活动记录函数有它,但我担心 order_by 没有。因此,也许它可以帮助您编写 SQL,您可以类似地创建 IN() 语句。
  • 我浏览了我的应用程序中的活动记录源代码,它似乎只是一个错误。我在几分钟内编写了 SQL,现在一切正常!
  • 但是按字段排序(id, `4`,`5`, `2`, `6`);我怎样才能从查询中删除`
【解决方案2】:

正如我在 SO 上找到的所有答案都只是半正确但都给出了很好的提示,我成功地实现了代码来检索按给定数组中的顺序排序的正确行集。

生成这样的sql:

SELECT * FROM (`product`) WHERE `id` IN (2, 34, 234) 
ORDER BY FIELD(`id`, 2, 34, 234)

使用此代码,而 $ids 包含数组 (2, 34, 234)。

// select from ... 
$this->db->where_in('id',$ids);
$this->db->_protect_identifiers = FALSE; // stop CI adding backticks
$order = sprintf('FIELD(id, %s)', implode(', ', $ids));
$this->db->order_by($order);
$this->db->_protect_identifiers = TRUE; // switch on again for security reasons
// get...

参见此处:http://ellislab.com/forums/viewthread/137157/#1058666

【讨论】:

    【解决方案3】:

    感谢最大的解决方案。

     $orde_num_string = implode(",",$order_num);
                $this->db->where_in("cir_order.order_num",$order_num);
                $this->db->_protect_identifiers = FALSE;
                $this ->db->order_by("FIELD(cir_order.order_num, $orde_num_string)");
                $this->db->_protect_identifiers = TRUE;
    

    【讨论】:

      猜你喜欢
      • 2013-02-22
      • 1970-01-01
      • 2013-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-19
      相关资源
      最近更新 更多