0

对 PHP 的 CodeIgniter 使用 Datamapper 1.8.1-dev,我正在尝试构建此查询以优先考虑列表顶部的一个国家/地区名称:

SELECT * FROM countries
ORDER BY CASE name WHEN 'Australia' THEN 1 ELSE 2 END, name

我的 Country 模型上的 PHP(扩展了 Datamapper):

$countries = new Country();
$countries->order_by("CASE name WHEN 'Australia' THEN 1 ELSE 2 END, name");
$countries->get_iterated();

Datamapper 将“CASE”解析为表名,构建此语法错误查询:

SELECT * FROM (`countries`)
ORDER BY `CASE` name WHEN 'Australia' THEN 1 ELSE 2 END, `countries`.`name`

我假设 CASE 案例没有被处理,因为这个流控制语句只是在 MySQL 5 中添加的?order_by在数据库检索后向表中添加列countries或使用 PHP 排序函数是我唯一的选择吗?

4

3 回答 3

5

我能够按顺序使用 case 语句。您只需要将 case 语句括在括号中。如果您不这样做,单词 case 将被视为列名并反引号。

$this->db->distinct(); 
$this->db->select('country');         
$this->db->from('distributors');
$this->db->where('country  != ', '');
$this->db->order_by("(CASE country WHEN 'UNITED STATES OF AMERICA' THEN '1' ELSE country END)");
于 2012-12-19T15:27:46.133 回答
1

Datamapperorder_by()只是$this->db->order_by().

不幸的是,根据CodeIgniter 文档,数据库类是唯一不可扩展的类。你将不得不通过修改核心来弄脏你的手。

进入system/database/DB_active_rec.php并搜索该order_by()功能。在函数的函数定义中添加第三个参数:

function order_by($orderby, $direction = '', $case = null)

滚动到函数的底部...就在分配$orderby_statement$this->ar_orderby[]写入之前:

if($case===true) $orderby_statement = "CASE " . $orderby_statement;

保存文件并进入application/libraries/datamapper.php并搜索该order_by()功能。注意,它只是一个包装器!

将其替换为:

public function order_by($orderby, $direction = '', $case = null)
{
    $this->db->order_by($this->add_table_name($orderby), $direction, $case);
    //For method chaining
    return $this;
}

现在,在你的控制器中,如果你true作为第三个参数传递给order_by(),并从第一个字符串参数中删除 CASE 关键字,你应该得到正确的语法。

希望这可以帮助。

于 2012-08-06T02:27:44.387 回答
0

由于 DataMapper 不支持 MYSQL 的 CASE 关键字,直接的解决方法是调用 SQL 使用query()方法:

$sql = "SELECT * FROM `countries` ORDER BY CASE `name` WHEN 'Australia' THEN 1 ELSE 2 END, `name`";
$countries = new Country();
$countries->query($sql);
于 2012-08-17T06:46:35.620 回答