I'm new to php and I've searched for the past hour and read all the documentation I could find and nothing is helping. I have a table that has a bunch of rows of data. I'm trying to pick one column from the whole table and add them all together. Here is what I got. All this tells me is how many rows there are that match my query, not the total sum of column I want. Any help is appreciated.
$res1 = $db->prepare('SELECT sum(distance) FROM trip_logs WHERE user_id = '. $user_id .' AND status = "2"');
$res1->execute();
$sum_miles = 0;
while($row1 = $res1->fetch(PDO::FETCH_ASSOC)) {
$sum_miles += $row1['distance'];
}
echo $sum_miles;
You're only returning one row in this instance. Modify your summed column to have an alias:
SELECT SUM(distance) AS totDistance FROM trip_logs ....
Now you can can fetch the row -
$row = $res1->fetch(PDO::FETCH_ASSOC);
echo $row['totDistance'];
No need to loop.
You can use SUM() without explicitely grouping your rows because if you use a group function in a statement containing no GROUP BY clause, it is equivalent to grouping on all rows.
If however you want to use the SUM() function for something slightly more complicated you have to group your rows so that the sum can operate on what you want.
If you want to get multiple sums in a single statement, for example to get the distance for all users at once, you need to group the rows explicitely:
$res1 = $db->prepare("
SELECT
SUM(distance) AS distance,
user_id
FROM trip_logs WHERE status = '2'
GROUP BY user_id
");
$res1->execute();
while ($row = $res1->fetch(PDO::FETCH_ASSOC))
{
echo "user $row[user_id] has runned $row[distance] km.\n";
}
This will return the sum of distances by user, not for all users at once.
Try this if you are using a Class :
class Sample_class{
private $db;
public function __construct($database) {
$this->db = $database;
}
public function GetDistant($user_id,$status) {
$query = $this->db->prepare("SELECT sum(distance) FROM trip_logs WHERE user_id =? AND status =?");
$query->bindValue(1, $user_id);
$query->bindValue(2, $status);
try{ $query->execute();
$rows = $query->fetch();
return $rows[0];
} catch (PDOException $e){die($e->getMessage());}
}
}
$dist = new Sample_class($db);
$user_id = 10;
$status = 2;
echo $dist->GetDistant($user_id,$status);
Related
Can somebody help me convert this Sql Query
SELECT *
FROM customer c
LEFT JOIN customer_order co
ON c.customer_number = co.customer_number
AND co.order_status IN ('preparing', 'prepared')
WHERE c.customer_status='unpaid'
AND c.order_status = 'unserve'
AND co.cus_ord_no IS null
into Codeigniter query just like the image below for example
When query statements do not have clauses that need to change conditionally then using $this->db-query() is the way to go.
$sql = "SELECT * FROM customer c LEFT JOIN customer_order co
ON c.customer_number=co.customer_number AND co.order_status IN ('preparing', 'prepared')
WHERE c.customer_status='unpaid' AND c.order_status='unserve' AND co.cus_ord_no IS null";
$query = $this->db->query($sql)->result();
echo json_encode($query);
It might be wise to include a check on the return from query() though because if it fails (returns false) then the call to result() will throw an exception. One way that can be handled is like this.
$query = $this->db->query($sql);
if($query !== FALSE)
{
echo json_encode($query->result());
return;
}
echo json_encode([]); // respond with an empty array
Query Builder (QB) is a nice tool, but it is often overkill. It adds a lot of overhead to create a string that literally is passed to $db->query(). If you know the string and it doesn't need to be restructured for some reason you don't need QB.
QB is most useful when you want to make changes to your query statement conditionally. Sorting might be one possible case.
if($order === 'desc'){
$this->db->order_by('somefield','DESC');
} else {
$this->db->order_by('somefield','ASC');
}
$results = $this->db
->where('other_field', "Foo")
->get('some_table')
->result();
So if the value of $order is 'desc' the query statement would be
SELECT * FROM some_table WHERE other_field = 'Foo' ORDER BY somefield 'DESC'
But if you insist on using Query Builder I believe this your answer
$query = $this->db
->join('customer_order co', "c.customer_number = co.customer_number AND co.order_status IN ('preparing', 'prepared')", 'left')
->where('c.customer_status','unpaid')
->where('c.order_status','unserve')
->where('co.cus_ord_no IS NULL')
->get('customer c');
//another variation on how to check that the query worked
$result = $query ? $query->result() : [];
echo json_encode($result);
You can do
public function view_customers()
{
$sql = "SELECT * FROM customer c LEFT JOIN customer_order co ON c.customer_number = co.customer_number AND co.order_status IN ('preparing', 'prepared') WHERE c.customer_status='unpaid' AND c.order_status = 'unserve' AND co.cus_ord_no IS null";
return $this->db->query($sql)->result();
}
You can use row() for one output to object, or row_array() if one output but array. result() is multiple objects and result_array() is multiple arrays.
My way do usually is like this:
Controller:
public function view()
{
$this->load->model('My_Model');
$data = new stdclass;
$data->user_lists = $this->my_model->view_users(array('nationality'=>'AMERICAN'));
}
Model:
public function view_users($param = null) //no value passed
{
$condition = '1';
if (!empty($param)) { //Having this will trap if you input an array or not
foreach ($param as $key=>$val) {
$condition .= " AND {$key}='{$val}'"; //Use double quote so the data $key and $val will be read.
}
}
$sql = "SELECT * FROM users WHERE {$condition}"; //Use double quote so the data $condition will be read.
// Final out is this "SELECT * FROM users WHERE 1 AND nationality='AMERICAN'";
return $this->db->query($sql)->result();
}
Earlier this day a asked a question about an update query. But now i want to select some things ( and it is working ) but I also want to order them and put a limit on it.
This is the code to select all the food :
public function getFood($id)
{
$id = (int)$id;
$rowset = $this->tableGateway->select(array('kindOfFood_id' => $id));
$row = $rowset->current();
if (!$row) {
throw new \Exception("Could not find row $id");
}
return $row;
}
But how can i do this :
Select * from KindOfFood ==> order by kindOfFood_votes DESC ?
I saw on the documentation you can do something like this, but it doesn't work with me?
$rowset = $artistTable->select(function (Select $select) {
$select->where->like('name', 'Brit%');
$select->order('name ASC')->limit(2);
});
Are you looking to return only single row or multiple rows.
Try this for multiple rows -
use Zend\Db\Sql\Select; //at the top of the page among other use statements.
public function getFood($id)
{
$id = (int) $id;
$select = new Select(TABLE_NAME); //CHANGE TABLE_NAME as per needs
$select->where('kindOfFood_id = ' . $id);
$select->order('kindOfFood_votes DESC');
$resultSet = $this->tableGateway->selectWith($select); //Will get array of rows.
//$row = $rowset->current(); THIS IS FOR RETURNING ONLY SINGLE ROW NOT ALL ROWS
if (!$resultSet) {
throw new \Exception("Could not find rows with food id - $id");
}
return $resultSet;
}
Can access the returned resultSet via loop. Eg: foreach
foreach($resultSet as $row) {
echo $row->kindOfFood_id; //or something
}
Note:
If you need only
Select * from KindOfFood order by kindOfFood_votes DESC
then remove the $select->where('kindOfFood_id = ' . $id); line from above.
I have this query in model:
public function Games() {
$q = $this->db->select('games.id, games.title, games.slug, games.dev_id, games.dev, games.plat_id, games.plat');
$q = $this->db->from('games');
$q = $this->db->join('rates', 'games.id = rates.game_id');
$q = $this->db->select_avg('rates.rate');
$q = $this->db->get();
return $q->result();
}
My goal is listing everything from games, additionally getting average rate from rates when available. Now it only shows those rows which are in both tables. How can I solve this?
Use this instruction
$this->db->select('games.id, games.title, games.slug, games.dev_id, games.dev, games.plat_id, games.plat');
$this->db->select_avg('rates.rate');
$this->db->from('games');
$this->db->join('rates', 'games.id = rates.game_id','left');
$this->db->group_by('rates.game_id');
$q = $this->db->get();
Left join will bring multiple results. using avg and group by will restrict to fetch only one row against each record.
I have created a simple function which takes user id and show total no. of post by the user id
function totalpost($user_id){
$sql = 'SELECT * FROM posts WHERE u_id='.$user_id;
$total = mysql_num_rows(mysql_query($sql)) or die(mysql_errno());
return $total;
}
Its working fine, but when 0 record found, it not returns anything.
I want to return 0 if there are no record found
Please help
function totalpost($user_id){
$sql = 'SELECT count(*) FROM posts WHERE u_id='.intval($user_id);
$res = mysql_query($sql)) or trigger_error(mysql_error().$sql);
$row = mysql_fetch_row($res);
return $row[0];
}
not because you need 0, but because you have to always use count() instead of selectiong all users posts which can be big load of data.
Try this query:
SELECT COUNT(*) FROM posts WHERE u_id=xx
By using the COUNT function you will guarantee a 0 will be returned even if no rows match the WHERE clause.
I want to find out how many rows are in a table. The database that I am using is a MySQL database. I already have a Db_Table class that I am using for calls like fetchAll(). But I don't need any information from the table, just the row count. How can I get a count of all the rows in the table without calling fetchAll()?
$count = $db->fetchOne( 'SELECT COUNT(*) AS count FROM yourTable' );
Counting rows with fetchAll considered harmful.
Here's how to do it the Zend_Db_Select way:
$habits_table = new Habits(); /* #var $habits_table Zend_Db_Table_Abstract */
$select = $habits_table->select();
$select->from($habits_table->info(Habits::NAME), 'count(*) as COUNT');
$result = $habits_table->fetchRow($select);
print_r($result['COUNT']);die;
Proper Zend-Way is to use Zend_Db_Select like this:
$sql = $table->select()->columns(array('name', 'email', 'status'))->where('status = 1')->order('name');
$data = $table->fetchAll($sql);
$sql->reset('columns')->columns(new Zend_Db_Expr('COUNT(*)'));
$count = $table->getAdapter()->fetchOne($sql);
This is how it's done in Zend_Paginator. Other option is to add SQL_CALC_FOUND_ROWS before your column list and then get the number of found rows with this query:
$count = $this->getAdapter()->fetchOne('SELECT FOUND_ROWS()');
You could do a
SELECT COUNT(*)
FROM your_table
$dbo->setFetchMode( Zend_Db::FETCH_OBJ );
$sql = 'SELECT COUNT(*) AS count FROM #table';
$res = $dbo->fetchAll( $sql );
// $res[0]->count contains the number of rows
I'm kind of a minimalist:
public function count()
{
$rows = $db->select()->from($db, 'count(*) as amt')->query()->fetchAll();
return($rows[0]['amt']);
}
Can be used generically on all tables.
Add count capability to your Zend_DB Object To count all table rows
public function count()
{
return (int) $this->_table->getAdapter()->fetchOne(
$this->_table->select()->from($this->_table, 'COUNT(id)')
);
}