简体   繁体   中英

Codeigniter: how do I select count when `$query->num_rows()` doesn't work for me?

I have a query which is returning a sum, so naturally it returns one row.
I need to count the number of records in the DB which made that sum.

Here's a sample of the type of query I am talking about (MySQL):

SELECT 
    i.id, 
    i.vendor_quote_id, 
    i.product_id_requested, 
    SUM(i.quantity_on_hand) AS qty, 
    COUNT(i.quantity_on_hand) AS count
FROM vendor_quote_item AS i
JOIN vendor_quote_container AS c 
    ON i.vendor_quote_id = c.id
LEFT JOIN company_types ON company_types.company_id = c.company_id
WHERE company_types.company_type =  'f'
AND i.product_id_requested =  12345678

I have found and am now using the select_min(), select_max(), and select_sum() functions, but my COUNT() is still hard-coded in.

The main problem is that I am having to specify the table name in a tightly coupled manner with something like $this->$db->select( 'COUNT(myDbPrefix_vendor_quote_item.quantity_on_hand) AS count' ) which kills portability and makes switching environments a PIA.

How can/should I get my the count values I am after with CI in an uncoupled way??

If you want a completely decoupled way of dealing with this, just run the query to get all the rows you'd add with SUM() and then add them together in PHP.

$sum = 0;
foreach($query->result() as $row)
{
    $sum += $row->quantity_on_hand;
}

Or something like that.

What about defining your table in a var or const and then doing the query like so:

define('VENDOR_QUOTE_ITEM', 'vendor_quote_item');
$this->$db->select( 'COUNT(' . VENDOR_QUOTE_ITEM . '.quantity_on_hand) AS count' );

This should be faster than $query->num_rows() as that would retrieve results and have PHP count them. The above code cuts to the chase and just asks the DB for the count without returning anything else (because it uses mysql's COUNT())

As for why $query->num_rows(); isn't working.. Make sure that var you call num_rows on a CI query result object. You should have something like this:

$your_query = $this->db->query("YOUR QUERY");
$your_query->num_rows() 

if you would like to use any MySQL function inside $this->db->select() function pass the second parameter as FALSE.

So it should be $this->$db->select( 'COUNT(myDbPrefix_vendor_quote_item.quantity_on_hand) AS count' , FALSE)

Well ... while it's a different direction than I initially envisioned, I ended up simply extending CI via the directions found HERE .

I added a select_count() method to match the existing select_min() , select_max() , and select_sum() methods.
This addition only applies to MySQL at this time, but it's a solid solution.

In case someone encounters a similar problem in the future, here's what I did:

  1. I dropped Simons "MY_Loader" directly into my "application/core" directory (didn't need to change a thing).
  2. Then I created a "MY_DB_mysql_driver" in the "application/core" directory, as per his instructions ... and made it looke like this: (sans comments for brevity)

.

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class My_DB_mysql_driver extends CI_DB_mysql_driver {

    final public function __construct($params) {
        parent::__construct($params);
        log_message('debug', 'Extended DB driver class instantiated!');

    }  /* method: __CONSTRUCT */

    final public function select_count($select = '', $alias = ''){

        if ( !is_string($select) OR $select == ''){
            $this->display_error('db_invalid_query');
        }
        if ($alias == ''){
            $alias = $this->_create_alias_from_table(trim($select));
        }
        $sql = 'COUNT('.$this->_protect_identifiers(trim($select)).') AS '.$alias;
        $this->ar_select[] = $sql;
        if ($this->ar_caching === TRUE){
            $this->ar_cache_select[] = $sql;
            $this->ar_cache_exists[] = 'select';
        }

        return $this;

    }  /* method: SELECT_COUNT */

}

Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM