【问题标题】:Convert complex JOIN query in codeigniter在 codeigniter 中转换复杂的 JOIN 查询
【发布时间】:2013-04-13 00:43:51
【问题描述】:

我正在将现有网站转换为 CI,并且我已经尝试了几天将此查询转换为 CI 友好代码:

$result = mysql_query("
    SELECT t1.mnumber, t1.mcontent, t1.mcontact
    FROM sms t1
    JOIN (
        SELECT mContent,mcontact, mnumber, MAX(mID) mID
        FROM sms
        GROUP BY mContact
    ) t2 ON t1.mcontact = t2.mcontact AND t1.mid = t2.mid
    GROUP BY t1.mContact
    ORDER BY t1.mid DESC
"); 

但是无论我尝试什么,我都无法在 CI 上得到正确的结果。

希望大家能帮帮我!


最接近我得到的结果是当我使用子查询破解时。 但是,出于沮丧,我删除了代码块并继续尝试。

我决定使用平面查询,就像上面发布的那样。这几乎给了我结果。

$query = $this->db->query("SELECT t1.mnumber, t1.mcontent, t1.mcontact FROM sms t1 JOIN (SELECT mContent,mcontact, mnumber, MAX(mID) mID FROM sms GROUP BY mContact) t2 ON t1.mcontact = t2.mcontact AND t1.mid = t2.mid GROUP BY t1.mContact ORDER BY t1.mid DESC"); $联系人 = 数组(); //向我们的数组添加数据 foreach($query->result() as $row){ 回声 $row->mNumber; } 返回$联系人;

但是,在我看来,我收到通知“消息:未定义的属性:stdClass::$mNumber”

所以还是没有结果,而且我更喜欢 CI 查询方法。

【问题讨论】:

  • 请问你能展示一下你到目前为止所做的尝试吗?你说你已经尝试了几天所以不需要展示所有东西,你可以展示你最接近你想要的结果:-)
  • 感谢您对我的帖子进行格式化 DaveRandom :)
  • 我的建议:不要。您编写了一个有效的查询。它是专门为某种类型的数据库构建的,因此您不需要查询构建器的与数据库无关的功能。你所做的只是为自己做更多的工作。

标签: php mysql sql codeigniter-2


【解决方案1】:

你可以像这样在codeigniter中使用它

$query = "  SELECT t1.mnumber, t1.mcontent, t1.mcontact
            FROM sms t1
            JOIN (
                SELECT mContent,mcontact, mnumber, MAX(mID) mID
                FROM sms
                GROUP BY mContact
            ) t2 ON t1.mcontact = t2.mcontact AND t1.mid = t2.mid
            GROUP BY t1.mContact
            ORDER BY t1.mid DESC"; 
$result =   $this->db->query($query);           
return $result->result();

第二种方法

您可以使用codeigniter的子查询方式来做到这一点你 将不得不破解codeigniter。像这样。转到系统/数据库/DB_active_rec.php 从这些函数中删除 public 或 protected 关键字

public function _compile_select($select_override = FALSE)
public function _reset_select()

现在可以写入子查询 现在这是您的带有活动记录的查询

$select =   array(
                'mContent',
                'mcontact',
                'mnumber',
                'MAX(mID) mID'
            );
$this->db->select($select);
$this->db->from('sms');
$this->db->group_by('mContact');
$subquery = $this->db->_compile_select(); // get the query string

$this->db->_reset_select(); // reset so it can newly form the query

unset($select);
$select =   array(
                't1.mnumber',
                't1.mcontent',
                't1.mcontact'
            );
$this->db->select($select);
$this->db->join('',"($subquery)");
$this->db->from('sms t1');
$this->db->group_by('t1.mContact');
$this->db->order_by('t1.mid','DESC');
$result =   $this->db->get();
return $result->result();

事情就完成了。干杯!!! 注意:在使用子查询时,您必须使用

$this->db->from('myTable')

而不是

$this->db->get('myTable')

运行查询。

【讨论】:

  • 我尝试了您的解决方案。使用解决方案 1,我得到未定义的索引错误。但是,如果我将查询更改为“SELECT * FROM SMS”,您的解决方案将完美运行。第二种解决方案,我得到一个 SQL 错误。所以还是没有运气:(
  • 问题已解决,我需要将我的字段命名为“AS”以便将它们传递给视图。谢谢!!
  • 我遇到致命错误:调用受保护的方法 CI_DB_active_record::_compile_select()
  • @itskawsar 您可能正在使用新版本,或者您可能没有删除公共或受保护的关键字。再次仔细阅读答案并关注。
  • 我遇到了函数 _compile_select();通过您的解决方案,我能够得到结果。谢谢。
【解决方案2】:

呃,那不应该是(猜测)......

 SELECT t1.mnumber
      , t1.mcontent
      , t1.mcontact
      , t1.mid
   FROM sms t1
   JOIN 
      ( SELECT mcontact
             , MAX(mID) mID 
          FROM sms 
         GROUP BY mContact
      ) t2
     ON t1.mcontact = t2.mcontact 
    AND t1.mid = t2.mid 
  ORDER 
     BY t1.mid DESC;

【讨论】:

  • 只需将其放入 CI 活动查询中即可。它不断输出错误
【解决方案3】:

这可能无法完全回答您的问题,但对于那些正在谷歌搜索"JOIN AND" 的人(这样您就可以在JoinAND 一些额外的东西,之前 WHERE 子句开始了),这是一个 hacky 方法:

$this->db->join('table_to_join', 'first_table.connect_id = table_to_join.id AND table_to_join.some_filter != 0');

绝对不漂亮,但这显然会强制AND 紧跟在JOIN 之后,然后再进入WHERE 的内容以完成对first_table 的其余查询

【讨论】:

    【解决方案4】:

    嗯,它很容易在 CI 版本 3+ 中实现

    $subQuery = $this->db->select( 'table2.*' )
      ->join( 'table3', 'table3.orderId = table2.fkOrderId', 'INNER' )
      ->where()->get_compiled_select( 'table2' );
    
    $this->db->select( 'table1.*' )
      ->join( '(' . $subQuery . ') AS b', 'b.`fkCouponId` = table1.couponId', 'LEFT', FALSE )
      ->get( 'table1' )
    

    提示:确保您没有在子查询部分上方使用任何查询构建器方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-25
      • 1970-01-01
      • 1970-01-01
      • 2021-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多