Am working on a student portal, below is the code i used for students position but, every user keeps getting 1st position. Every student seems to have 1st position, when they check their results from the front view. Cant seem to figure out where the problem is from in the code
function get_position($student, $class, $session, $term){
$this->db->select('*');
$this->db->from('result');
$this->db->where(array( 'class_id'=>$class, 'Session'=>$session, 'Term'=>$term));
$this->db->order_by('Total', 'asc');
$other_results = $this->db->get()->result_array();
$this->db->select("*");
$this->db->from('result');
$this->db->where(array('class_id'=> $class, 'Session'=>$session, 'Term'=>$term, 'StudentID'=>$student ));
$student_result = $this->db->get()->result_array();
$student_total = $this->get_student_total($student_result);
$position =1;
foreach($other_results as $res){
if($student_total < $res['Total']){
$position++;
}
}
return $position;
}
function get_student_total($result){
$total = 0;
foreach($result as $res){
$total+= $res['Total'];
}
return $total;
}
}
?>
I am assuming that the result table may have many records for a given studentID. Several test scores (Totals) for each student during the term right?
This should do the trick
public function get_position($student, $class, $session, $term)
{
//I like to use db method chaining.
$ranking = $this->db->select('StudentID')
->select_sum('Total', 'sumScore')
->from('result')
->where(array('class_id' => $class, 'Session' => $session, 'Term' => $term))
->group_by('StudentID')
->order_by('sumScore', 'desc')
->get()->result_array();
//The code above retrieves results from a query statement that looks like this:
//SELECT `StudentID`, SUM(`Total`) as sumScore
//FROM `result` where `class_id` = $class and `Session` = $session and `Term` = $term
//GROUP BY `StudentID`
//order by `sumScore` desc
$position = 1;
foreach($ranking as $rank)
{
if($rank['StudentID'] !== $student)
{
++$position;
}
else
{
return $position;
}
}
return NULL; //to indicate studentID was not found
}
Related
Am trying to update multiple records in the database but my case I have a column total, which I want to update to different values. I haven't tried much here but hope I could get a clue on how to go about this.
My controller
public function update_record()
{
$id = ["19821", "19923", "19966", "19967"];
$total = ["8", "118", "90", "100"];
if ($this->some_model->batch_data('records', $total, $id) == true) {
echo "yes";
} else {
echo "no";
}
}
The Model
public function batch_data($table, $data, $where)
{
$this->db->where_in('id',$where);
$this->db->set('total',$data);
$this->db->update($table);
return true;
}
I have not tested this yet but currently looking for a more and efficient way of doing this.
If you still want to update multiple records using the update_batch method, you could first assign the id and total as key-value arrays, then use the update_batch method.
Controller :
public function update_record()
{
$id = ["19821", "19923", "19966", "19967"];
$total = ["8", "118", "90", "100"];
$update_data = [];
foreach ($id as $key => $value) {
$update_data[] = [
'id' => $value,
'total' => $total[$key]
];
}
if ($this->some_model->batch_data('records', $update_data) == true) {
echo "yes";
} else {
echo "no";
}
}
Model :
public function batch_data($table, $data)
{
$this->db->update_batch($table, $data, 'id'); // this will set the id column as the condition field
return true;
}
Output :
// preview query output :
// UPDATE `records`
// SET
// `total` =
// CASE
// WHEN `id` = '19821' THEN 8
// WHEN `id` = '19923' THEN 118
// WHEN `id` = '19966' THEN 90
// WHEN `id` = '19967' THEN 100
// ELSE `total`
// END
// WHERE `id` IN ('19821', '19923', '19966', '19967')
As per my comment. This is a method that combines the array in to key/value pairs and updates them 1x1 wrapped in a transaction (so if one query fails nothing changes).
This is the method I would personally use as I don't like update_batchs internal workings (cases).
$id = ["19821", "19923", "19966", "19967"];
$total = ["8", "118", "90", "100"];
$combined = array_combine($id, $total);
if (count($combined) > 0) {
$this->db->trans_start();
foreach ($combined as $id => $total) {
$this->db->set('total', $total);
$this->db->where('id', $id);
$this->db->update('sometable');
}
$this->db->trans_complete();
return $this->db->trans_status();
}
return true;
Try this, Only for single where condition
Controller:
public function update_record()
{
$tableName = "records";
$id = ["19821", "19923", "19966", "19967"];
$total = ["8", "118", "90", "100"];
$update_data = [];
foreach ($id as $key => $value) {
$update_data[] = [
'id' => $value,
'total' => $total[$key]
];
}
$whereKey = 'id';
$this->$this->some_model->batch_data($tableName, $updateData, $whereKey);
}
Model:
public function batch_data($tableName, $updateData, $whereKey)
{
$this->db->update_batch($tableName, $updateData, $whereKey);
}
I have a question
Let say we have this 2 tables in our database
first table : category_lists
second table: data_category
so if list_data_id is equal to 1 meaning that it has 2 data if you look at data_category table which is 6 and 7
Now what I want is to query from category_list table so that 6 and 7 will echo Car Wreckers and Cash For Cars.
This is what my code looks like:
below is my controller:
public function index($listing_name)
{
$this->load->view('layouts/head_layout_seo');
$this->load->view('layouts/head_layout');
$data['main_view'] = 'listings/main_view';
$data['listing_data'] = $this->Listing_model->get_detail_listing($listing_name);
$list_id = $data['listing_data']->list_data_id; // this is what I get list_data_id is equal to 1
$data['category_ads'] = $this->Ads_model->get_ads($list_id); // this is what you need to look
$this->load->view('layouts/main', $data);
$this->load->view('layouts/footer_layout');
}
below is my model:
public function get_ads($list_id)
{
$this->db->where('list_data_id', $list_id);
$query = $this->db->get('data_category');
$query = $query->result();
//return $query;
if (count($query) > 0) {
for ($i=0; $i < count($query); $i++) {
foreach ($query as $value) {
$this->db->where('category_lists_id', $value->category_lists_id);
$querys = $this->db->get('category_lists');
//print_r($query);
return $querys->result();
}
}
}
}
below is my view:
foreach ($category_ads as $value) {
<p><?php echo $value->categories; ?></p> }
with the code above I get only 1 data which is Car Wreckers as you can see from the table, it supposes to show 2 data Car Wreckers and Cash For Cars
Can anyone help me with this?
Thank You
Try this, in your model so no need to call DB two times and no need to loop
public function get_ads($list_id)
{
$this->db->select('cl.category_lists_id,cl.categories');
$this->db->from('category_lists cl');
$this->db->join('data_category dc','cl.category_lists_id = dc.category_lists_id');
$this->db->where('dc.list_data_id',$list_id);
$query = $this->db->get();
if($query->num_rows() > 0){
return $query->result();
}else{
return array();
}
}
I want to loop through the results of a query and then compare each results to an input field, if the value is repeated it must return false if not the result is true, I know that I could use unique index in database to avoid repeated values and then catch the error, but in this case repeated values are possible but they can´t both be "active" there a column called "status" with two values A or I (active and inactive) so "clabe" value can be repeated only when one is active and the other inactive.
Controller:
function agregar()
{
$this->load->helper('date');
date_default_timezone_set('America/Mexico_City');
$now = date('Y-m-d H:i:s');
$Interno = $this->input->post('intern');
$clabe = $this->input->post('clabe2') . $this->input->post('control2');
$cve_banco = $this->input->post('cve_banco');
$Banco = $this->input->post('Banco2');
$Observaciones = $this->input->post('Observaciones');
$data = array(
'Interno' => $Interno,
'clabe' => $clabe,
'cve_banco' => $cve_banco,
'Banco' => $Banco,
'Observaciones' => $Observaciones,
'Fecha_alta' => $now,
);
if($this->consultas_M->insert($data) == true){
//redirect('Inicio/busqueda', 'refresh');
} else{
echo "Hubo un problema al insertar";
}
}
Model:
function insert($data)
{
$clabe = $this->input->post('clabe2') . $this->input->post('control2');
$this->db->select('Clabe');
$this->db->where('Status =', 'A');
$query= $this->db ->get('cuentas');
return $query->row();
foreach ($query as $row) {
$i = $row;
if ($clabe = $i) {
return false;
} else {
$this-> db -> insert('cuentas', $data);
if ($this->db->affected_rows() > 0) {
return true;
}
}
}
}
Why would you want to have possible duplicated index ? If you want to have different rows with a common "index" for some reason you can create a column called index or something and add in your WHERE clause that index.
PS: in your model in the foreach loop's if condition use :
if ($clabe == $row){...
instead of
$i = $row
if ($clabe = $i){...
I solved myself the issue, i´m posting in in case it helps anybody, it was easier than I thought.
function insert($data, $clabe)
{
$Status = 'A';
$clabe = $this->input->post('clabe2') . $this->input->post('control2');
$this->db->select('Clabe');
$this->db->where('Status =', $Status);
$this->db->where('Clabe =', $clabe);
$q= $this->db ->get('cuentas');
if($q -> num_rows() > 0){
return false;
}else{
$this-> db -> insert('cuentas', $data);
return true;
}
And this is the controller:
if($this->consultas_M->insert($data, $clabe) == true){
redirect('Inicio/busqueda', 'refresh');
} else{
echo "There was a problem";
$this->load->view('errors/error');
}
The only thing I needed and wasn´t doing was to select the "clabe" I wanted and then compare it with the input where user writes this "clabe". And then just a simple if-else statement.
function insert($data)
{
$Status = 'A';
$clabe = $this->input->post('clabe2') . $this->input->post('control2');
$this->db->select('Clabe');
$this->db->where('Status', $Status);
$query= $this->db ->get('cuentas');
$flag=true;
foreach ($query as $row) {
$i = $row;
if ($clabe = $i){
$flag=false;
}
}
if($flag){
$this-> db -> insert('cuentas', $data);
if ($this->db->affected_rows() > 0) {
$flag= true;
}
}
return $flag;
}
Your code will add it on first else block ad return. Instead it should check all the rows first to decide.
I wanting to be able to join two tables togeather.
How ever because I my forum table has column "name" and my forum_categories column "name"
I am not able to display both names.
On my select() if I use like $this->db->select('f.name, fc.name', false); it only displays name from forum_categories
array(1) { [0]=> array(1) { ["name"]=> string(17) "News & Discussion" } }
Question how can I get both names to show from both columns and
tables.
Note: I only want to be able to use $result['name'] in my foreach loop.
So the out put I would like it to be
General
News & Discussion
Lounge
I have looked at
CodeIgniter ActiveRecord field names in JOIN statement
codeigniter - select from 2 tables with same column name
Model
public function get_forums() {
$this->db->select('f.name, fc.name', false);
$this->db->from('forum as f');
// tried $this->db->join('forum_categories as fc', 'fc.forum_id = f.forum_id');
$this->db->join('forum_categories as fc', 'fc.forum_categories_id = f.forum_id');
$query = $this->db->get();
if ($query->num_rows() > 0) {
return $query->result_array();
} else {
return false;
}
}
Controller
<?php
class Forums extends MY_Controller {
public function __construct() {
parent::__construct();
}
public function index() {
$data['label'] = '';
$data['forums'] = array();
$results = $this->get_forums();
var_dump($results);
if (isset($results)) {
foreach ($results as $result) {
$data['forums'][] = array(
'name' => $result['name'], // Only want to use single variable.
);
}
}
$data['header'] = Modules::run('admin/common/header/index');
$data['footer'] = Modules::run('admin/common/footer/index');
$this->load->view('template/forum/list_forum_view', $data);
}
public function get_forums() {
$this->db->select('f.name, fc.name', false);
$this->db->from('forum as f');
$this->db->join('forum_categories as fc', 'fc.forum_categories_id = f.forum_id');
$query = $this->db->get();
if ($query->num_rows() > 0) {
return $query->result_array();
} else {
return false;
}
}
}
update
works fine with code below but would rather just use one lot of join()
public function get_forums() {
$this->db->select("*");
$this->db->from('forum');
$query = $this->db->get();
foreach ($query->result_array() as $f) {
$data[] = array(
'name' => $f['name']
);
$this->db->select("*");
$this->db->from('forum_categories');
$query = $this->db->get();
foreach ($query->result_array() as $fc) {
$data[] = array(
'name' => $fc['name']
);
}
}
return $data;
}
Try This , It Will Work .
public function get_forums() {
$this->db->select('f.name as forum_name, fc.name as forum_categories_name', false);
$this->db->from('forum f');
// tried $this->db->join('forum_categories fc', 'fc.forum_id = f.forum_id');
$this->db->join('forum_categories fc', 'fc.forum_categories_id = f.forum_id');
$query = $this->db->get();
if ($query->num_rows() > 0) {
return $query->result_array();
} else {
return false;
}
}
From what i see in your updated question. What you need is UNION and not JOIN. You can use get_compiled_select() to build both query before concat with UNION.
public function get_forums() {
$forum = $this->db->select('name')->get_compiled_select('forum');
$forum_categories = $this->db->select('name')->get_compiled_select('forum_categories');
$query = $this->db->query($forum.' UNION '.$forum_categories);
if ($query->num_rows() > 0) {
return $query->result_array();
} else {
return false;
}
}
Simply use
AS
keyword, because when you try to print it, that AS keyword give you optional name for your column.
Here i have two table which have same column name "name" so i have changed those with AS keyword.
Ex:
$this->db->select('tbl_category.id_category,tbl_category.name AS cat_name,
tbl_subject.id_subject,tbl_subject.name AS sub_name');
In result
Array ( [0] => Array ( [id_category] => 9 [cat_name] => OL [id_subject] => 13 [sub_name] => Science )
So it is simple solution from the SQL language
I have two tables sport_tbl, match_tbl. In sport_tbl, i defined sport_name such as cricket. In match_tbl, I have match_name,match_date,sport_id.
I want to show match_date of every sport_name (ex. i am showing match_date list for cricket sport and i want to show every date has match_name list).
I want to show one distinct match_date.
Image
my controller code:-
$url = 'cricket' // for example first sport_name
$data['getSportMatch'] = $this->user_model->getSportMatch($url);
my model code:-
public function getSportMatch($sport)
{
$query = $this->db->get_where('match_tbl',array('sport_name' => $sport));
if($query->num_rows > 0)
{
foreach($query->result() as $item){
$data[] = $item;
}
return $data;
}
}
my code in view:-
<div><?php foreach($getSport as $item): ?><h4><?= $item->sport_name; ?></h4><div><?= foreach($getSportMatch as $item): ?>
match_date)) ?>here i want to show list match_name of every match_date
My table structure images
1) sport_tbl
2) match_tbl
3) another match_tbl
you can solve this in model easily. if i did not understand wrong . you need 2 function in model.
1. will get sport names
2. will get matches of given sport name
//model functions
function get_sports(){
$data = array();
$sports = $this->db->select('sport_name')->from('sport_tbl')->get()->result();
if($sports)
{
foreach($sports as $sport){
$data[$sport->sport_name] = $this->get_matches($sport->sport_name);
}
return $data;
}
}
function get_matches($sport_name){
$matches = $this->db->select('*')->from('match_tbl')->where('sport_name',$sport_name)->get()->result();
return $matches;
}
so in view data will be something like this
$data => array(
'cricket'=> array(0 => array(
'match_id' => 11,
'sport_id' = 2 .....
)))
Try this coding ...
public function getSportMatch($sport)
{
$query = $this->db->query("SELECT * FROM sport_tbl as st INNER JOIN match_tbl as mt ON st.sport_id = mt.sport_id WHERE st.sport_name ='".$sport."'");
if($query->num_rows > 0)
{
$query_result = $query->result_array();
$final_result = array();
foreach($query_result as $result ) {
$date = $result['match_date'];
$final_result[$date][] = $result;
}
return $final_result;
}
}
View Coding :-
if(isset($final_result)) {
foreach($final_result as $result) {
echo $result['match_date']; // First display match date
if(isset($result['match_date'])) {
foreach($result['match_date'] as $match) {
echo $match['match_name']; // Second listout the match name
}
}
}
}