I am trying to perform reporting from database where user will enter his own criteria to pull data,
Here is modal function of my fetch,
public function fetch_insight($insight_start, $insight_end, $user_id,
$manager_id, $category_id, $expense_method, $report_status, $policy_breach)
{
$array = array('ec_expensedetails.expense_date >' => $insight_start,
'ec_expensedetails.expense_date <=' => $insight_end,
'ec_reports.report_status' => $report_status,
'ec_expensedetails.user_id' => $user_id,
'ec_reports.manager_id' => $manager_id,
'ec_expensedetails.category_id' => $category_id,
'ec_expensedetails.expense_method' => $expense_method,
'ec_expensedetails.policy_breach' => $policy_breach);
$this->db->where($array);
$this->db->select('ec_expensedetails.*');
$this->db->select('ec_expensecategory.*');
$this->db->select('ec_reports.*');
$this->db->select('ec_users.*');
$this->db->from('ec_users');
$this->db->join('ec_expensedetails', 'ec_expensedetails.user_id = '.$user_id,'INNER');
$this->db->join('ec_expensecategory', 'ec_expensecategory.category_id = ec_expensedetails.category_id','INNER');
$this->db->join('ec_reports', 'ec_reports.report_status = ec_reports.report_status ','INNER');
return $this->db->get()->result_array();
}
Now in when user selects fields like $user_id, $manager_id, $category_id, it gives me result array,
Problems,
But example if user just want to pull data with dates without any other where conditions, how can i remove that other where conditions of user_id, manager_id, category_id?
report_status in JOIN is column value field, i can join tables with ID field, but how can i JOIN table with value field in codeigniter? see last join in code.
Thanks,
Related
I have a few tables that are joined through a distant relationship - for example:
A.id = B.a_id, B.id = C.b_id, C.id = D.c_id
And given A.id, I want to delete all the rows in D that are associated with A.id.
Since Model::deleteAll() does not accept any joins, only conditions, how do I go about it?
All the models (A, B, C, D) already have belongTo relationships defined.
My last resort would be raw SQL, but I would like to know if there's a way in CakePHP to do it.
I could not find similar questions as they all were about deleting ALL the associated data, rather than just one table's data via an associated key.
Use Containable behavior to find D records
public function deleteD($idA){
$this->ModelA->Behaviors->load('Containable');
$options = array(
'contain' => array(
'ModelB' => array(
'ModelC' = array(
'ModelD'
)
)
),
'conditions' => array('ModelA' => $idA)
);
$findDIds = $this->ModelA->find('all',$options);
debug($findDIds); // find right path to ModelD
$ids = Hash::extract($findDIds,'{n}.ModelD.id');
$this->loadModel('ModelD');
foreach($ids as $id){
$this->ModelD->delete($id);
}
}
Note, I not tested this function.
I have a table with three fields
id (primary key / auto incremented)
product_name
group_id
my problem is when i insert multiple rows through form the whole group of rows should get same groupId & it should be incremented by 1 at the time of submission as there can be many users submitting the form at the same time. I dont know how to do it. Please help.
my model
function get_last_group_id() {
$this->db->select('group_id');
$this->db->from('mytable');
$this->db->order_by('group_id', 'DESC');
$this->db->limit('1');
$query = $this->db->get();
return $query->result();
}
function save_rows($ids,$product_names,$group_ids){
$this->db->trans_begin();
$ndx=0;
foreach($ids as $id){
$data = array(
'id' => $id,
'product_name' => $product_names[$ndx],
'group_id' =>$group_ids[$ndx],
$this->db->insert("product_details",$data);
$this->db->update($this->table);
$ndx++;
}
There is no need to make seperate function for getting group id and set id field also if that is auto incre
function save_rows($ids,$product_names){
$this->db->trans_begin();
$ndx=0;
$group_id = $this->db->select("MAX(group_id) as group_id")
->from("mytable")
->get()->row_array();
foreach($ids as $id){
$data = array(
'product_name' => $product_names[$ndx],
'group_id' =>$group_id['group_id']+1,
);
$this->db->insert("product_details",$data);
$ndx++;
}
You can create a new table say 'groups'
fields: id(Auto Increment) and group_name (varchar)
generate group name randomly.
Then before inserting products create a new group then you will get a new groupID that will be unique.
Then using that groupID you can carry your option forward
I cannot get primary id array, I try to debug it happens when use joinLeft function
Here my script
//setIntegrityCheck to false to allow joins
$roomModel = new self();
$select = $roomModel->select(Zend_Db_Table::SELECT_WITH_FROM_PART)
->setIntegrityCheck(FALSE);
//performs join aliasing table room_type to t
$select->join(array('t' => 'room_types'), 't.room_type_id = rooms.room_type_id AND num_beds> '.$number_beds);
////performs join aliasing table room_status to s
$select->join(array('s' => 'room_statuses'), 's.room_status_id = rooms.room_status_id');
$select->joinLeft(array('chin' => 'checkin'), 'chin.checkin_date > '.$checkin.' AND chin.checkin_date <'.$checkout.'');
$select->joinLeft(array('chout' => 'checkout'), 'chout.checkout_date >'.$checkin.' AND chout.checkout_date <'.$checkout.'');
$result = $roomModel->fetchAll($select);
What causes it to happen?
one of the tables you are joining also may contain a column named like your primary key and if the row does not exist it will override it with null.
you should choose which columns you want from each table:
$select->join('table', 'condition', array('column1', 'column2', 'column3'));
$select->joinLeft('table', 'condition', array('column1', 'column2', 'column3'));
I simply want to return all rows from a users table but selected fields, and possible concat 2 fields.
normal sql could have just been:
SELECT id, CONCAT(`first_name`,`last_name`) AS `fullname` FROM `users`
But trying to achieve this in cake is a nightmare:
$users = $this->User->find("all") = returns everything
$users = $this->User->find("list",array("fields" => " ...) does not work either.
Can anyone please help me on how to use the cake model to achieve the simple query and return results
You are close:
$this->User->find('all', array('fields' => array('CONCAT(first_name,last_name) AS fullname', 'otherfield'), 'contain' => array());
I'm new to PHP/MySQL and super-new to CodeIgniter..
I have information in many MySQL tables. I want to retrieve it with JOIN where the tables primary keys are equal to $variable... How can I do it and get all the fields without the primary key field???
What I'm doing now is this (only two tables joined here):
function getAll($id) {
$this->db->select('*');
$this->db->from('movies');
$this->db->join('posters', 'movies.id= posters.id');
// WHERE id = $id ... goes here somehow...
$q = $this->db->get();
if ($q->num_rows() == 1) {
$row = $q->row();
$data = array(
'id' => $row->id,
'title' => $row->title,
'year' => $row->year,
'runtime' => $row->runtime,
'plotoutline' => $row->plotoutline,
'poster_url' => $row->poster_url
);
}
$q->free_result();
return $data;
id (PK), title, year, runtime and plotoutline are columns from the first table and poster_url is a field from the second table. The second table also contains an ID (PK) column that I don't want to Retrieve because I already have.
Jon is right. Here's an example:
$this->db->select('movies.id,
movies.title,
movies.year,
movies.runtime as totaltime,
posters.poster_url');
$this->db->from('movies');
$this->db->join('posters', 'movies.id= posters.id');
$this->db->where('movies.id', $id);
$q = $this->db->get();
This will return objects that have ->id, ->title, ->year, ->totaltime, and ->poster_url properties. You won't need the additional code to fetch the data from each row.
Don't forget, if the Active Record syntax gets a little unwieldy, you can use full SQL queries and get the same results:
$sql = "SELECT movies.id,
movies.title,
movies.year,
movies.runtime as totaltime,
posters.poster_url
FROM movies
INNER JOIN posters ON movies.id = posters.id
WHERE movies.id = ?"
return $this->db->query($sql, array($id))->result();
Both forms will ensure that your data is escaped properly.
CodeIgniter Active Record
Query Binding in CodeIgniter
An asterisk will return all the fields. To return a subset of these, i.e. all fields apart form the repeated id field, simply list the columns which you require rather than use '*'.
It is often a good idea to not use asterisk anyway. In the future of the app, someone may add a large field to the table which will be surplus to your requirements, and will slow your queries.
Simply put with method chaining:
$this->db->select('*')
->from('movies')
->join('posters', 'movies.id= posters.id')
->where('movies.id', $id)
->get();
$this->db->select('*');
$this->db->from('blogs');
$this->db->join('comments', 'comments.id = blogs.id');
$query = $this->db->get();