On my models I try to write a php model that will get me a associative array from a database. But I don't quite know how to approach this.
So after I execute this SQL query:
SELECT balance_events.weight,balance_events.added_date,
balance_entries.mid FROM balance_events, balance_entries
WHERE balance_entries.added_date BETWEEN '2016-08-02' AND '2016-08-03'
AND balance_entries.ptid =12
AND balance_entries.beid = balance_events.id
I will get this table:
And from that table I want to extract a asociative array that it will look like this:
count = ['13'=>1, '6'=>4, '16'=>3, '4'=>3]
where 'mid'=>number of how many times that mid can be found in the table.
ex. mid '13'=>1 cause you can found it only once.
I think that I will have to use SQL COUNT function, but how I can aggregate all of this in a PHP model in codeigniter? I know how to configure controller and view, but I don't know how to actually do the actual php model that will get me the desired array.
Try this query may help you ,
$result = $this->db->select('balance_events.weight,balance_events.added_date,COUNT(balance_entries.mid) as mid_count')
->from('balance_events, balance_entries')
->where('balance_entries.added_date BETWEEN "2016-08-02" AND "2016-08-03" ')
->where('balance_entries.ptid','12')
->where('balance_entries.beid','balance_events.id')
->group_by('balance_entries.mid')
->get();
return $result->result_array();
I'm not sure how you would create this in SQL but since you tagged php, I wrote a function that would do just this.
<?php
$query = array(array("mid"=>13), array("mid"=>2), array("mid"=>13), array("mid" =>6), array("mid" => 13), array("mid" => 6));
function createMidArray($queryResult){
$returnArray = array();
foreach ($queryResult as $qr){
$returnArray[$qr['mid']]++;
}
return $returnArray;
}
print_r(createMidArray($query));
?>
The output of this was Array ( [13] => 3 [2] => 1 [6] => 2 ) which matches up to my inputted $query (which is a 2D array). I'm expecting the output of your query is stored in a similar array, but with more data and keys
Related
I'm trying to insert an array of data into a table in database but an error said Array to string conversion error
This is the post function in my controller, first i post an array of data. The values of the array will be the names, and numbers, they are not id. The id is only kodejdwl. This will be pass to my model
function index_post() {
$data = array(
'kodejdwl' => $this->post('kodejdwl'),
'tahun_akad' => $this->post('kode_tahun_akad'),
'semester' => $this->post('semester'),
'mk' => $this->post('mk'),
'ruangan' => $this->post('ruangan'),
'nama_dosen' => $this->post('nama_dosen'),
'namakelas' => $this->post('nama_kelas'),
'jam_mulai' => $this->post('jam_mulai'),
'jam_selesai' => $this->post('jam_selesai'),
);
}
After the data from above code is passed to the model. I created some new variables which are the id of each the name of the value in the array data. e.g if the value of data['mk'] is Website then the id will be 1 and that id will be stored in variable $kodemk and i do it to each value in the data. Then i created new_data which stores array of the id's which i previously made. Then i insert that array into one table in my database. I thought it would be fine but it said Array to string conversion error. What should i do so i could insert that array into the table in my database?
public function insert($data){
$this->db->select('thn_akad_id');
$tahunakad_id = $this->db->get_where('tik.thn_akad',array('tahun_akad'=>$data['tahun_akad'],'semester_semester_nm'=>$data['semester']))->result();
$this->db->flush_cache();
$this->db->select('kodemk');
$kode_mk = $this->db->get_where('tik.matakuliah',array('namamk'=>$data['mk']))->result();
$this->db->flush_cache();
$ruangan = $this->db->get_where('tik.ruangan', array('namaruang' => $data['ruangan']), 1)->result();
$this->db->flush_cache();
$this->db->select('nip');
$nip_dosen = $this->db->get_where('tik.staff',array('nama'=>$data['nama_dosen']))->result();
$this->db->flush_cache();
$this->db->select('kodeklas');
$kodeklas = $this->db->get_where('tik.kelas',array('namaklas'=>$data['namakelas']))->result();
$this->db->flush_cache();
$this->db->select('kode_jam');
$kode_mk = $this->db->get_where('tik.wkt_kuliah',array('jam_mulai'=>$data['jam_mulai'],'jam_selesai'=>$data['jam_selesai']))->result();
$this->db->flush_cache();
$new_data = array(
'kodejdwl' => $data['kodejdwl'],
'thn_akad_thn_akad_id' => $tahunakad_id,
'matakuliah_kodemk' => $kode_mk,
'ruangan_namaruang' => $ruangan,
'staff_nip' => $nip_dosen,
'kelas_kodeklas' => $kodeklas,
);
$insert = $this->db->insert('tik.jadwal_kul', $new_data);
return $this->db->affected_rows();
}
You probably want to use row() instead of result() because it'll contain only one result that you want. If you want to use result() and store multiple values then you'll have to use implode to concatenate them and store it as a string.
I've written a possible solution for your problem; Some things were missing, so I've mentioned them in the comments. See if this helps you.
public function insert($data){
$this->db->select('thn_akad_id');
$tahunakad_id = $this->db->get_where('tik.thn_akad',array('tahun_akad'=>$data['tahun_akad'],'semester_semester_nm'=>$data['semester']))->row(); // use row here
$this->db->flush_cache();
$this->db->select('kodemk');
$kode_mk = $this->db->get_where('tik.matakuliah',array('namamk'=>$data['mk']))->row();
$this->db->flush_cache();
// remove your_ruangan_column with your desired column name
$this->db->select('your_ruangan_column');
$ruangan = $this->db->get_where('tik.ruangan', array('namaruang' => $data['ruangan']), 1)->row();
$this->db->flush_cache();
$this->db->select('nip');
$nip_dosen = $this->db->get_where('tik.staff',array('nama'=>$data['nama_dosen']))->row();
$this->db->flush_cache();
$this->db->select('kodeklas');
$kodeklas = $this->db->get_where('tik.kelas',array('namaklas'=>$data['namakelas']))->row();
$this->db->flush_cache();
// Not sure where this ↓↓ is being used but you can use it the same way as others
$this->db->select('kode_jam');
// duplicate variable name here ↓↓ (fix this)
$kode_mk = $this->db->get_where('tik.wkt_kuliah',array('jam_mulai'=>$data['jam_mulai'],'jam_selesai'=>$data['jam_selesai']))->row();
$this->db->flush_cache();
$new_data = array(
'kodejdwl' => $data['kodejdwl'],
'thn_akad_thn_akad_id' => $tahunakad_id->thn_akad_id, // {$tahunakad_id} consists an object with the key {thn_akad_id}-- table_column_name
'matakuliah_kodemk' => $kode_mk->kodemk, // ...
'ruangan_namaruang' => $ruangan->your_ruangan_column, // ...
'staff_nip' => $nip_dosen->nip, // ...
'kelas_kodeklas' => $kodeklas->kodeklas // ...
);
$insert = $this->db->insert('tik.jadwal_kul', $new_data);
return $this->db->affected_rows();
}
Your are making a total of 7 separate trips to the database. Best practice recommends that you always minimize your trips to the database for best performance. The truth is that your task can be performed in a single trip to the database so long as you set up the correct INSERT query with SELECT subqueries.
I don't know what your non-English words are, so I will use generalized terms in my demo (I've tested this successfully in my own CI project). I am also going to reduce the total subqueries to 3 to reduce the redundance in my snippet.
$value1 = $this->db->select('columnA')->where('cond1', $val1)->get_compiled_select('childTableA');
$value2 = $this->db->select('columnB')->where('cond2', $val2)->get_compiled_select('childTableB');
$value3 = $this->db->select('columnC')->where('cond3', $val3)->get_compiled_select('childTableC');
return (int)$this->$db->query(
"INSERT INTO parentTable
(column1, column2, column1)
VALUES (
($value1),
($value2),
($value3)
)"
);
// to mirror your affected rows return... 1 will be returned on successful insert, or 0 on failure
Granted this isn't using the ActiveRecord technique to form the complete INSERT query, but this is because CI doesn't allow subqueries in the VALUES portion (say, if you were to use the set() method). I am guessing this is because different databases use differing syntax to form these kinds of INSERTs -- I don't know.
The bottom line is, so long as you are fetching a single column value from a single row on each of these sub-SELECTs, this single query will run faster and with far less code bloat than running N number of individual queries. Because all of the variables involved are injected into the sql string using get_compiled_select() the stability/security integrity should be the same.
I have this following Yii 2 query
$find = People::find()->where(['c_id' => $c_id])->orderBy('totals DESC, id DESC')->all();
So imagine this query was an array. Everything found by this query has an "id" attribute.
Since it's sorted by "totals", I essentially want to return the position in the array where I can find this specific id.
Currently, I'm using this code.
foreach ($find as $t) {
$arr[] = $t->id;
if ($t->id == $id) {
break;
}
}
$key = count($arr);
return $key;
However, this code is vany wayow on a 100k+ result query.
Is there anyway to speed this up?
You could get the result as an array (instead of object) as
$find = People::find()->where(['c_id' => $c_id])
->orderBy('totals DESC, id DESC')
->asArray()
->all();
then you could find your value using array_search()
$my_index = array_search($id,$find);
but for 100k+ you should find using a direct select in db...instead tha looping on php or load all in php and scan with array_search()
To get array from query in YII, you can use queryAll();
$find = People::find()->where(['c_id' => $c_id])->orderBy('totals DESC, id DESC')->queryAll();
OR, another way to convert the object into an array is:
$find = json_decode(json_encode($find), true); // to convert all data into array.
And once you get results in array, you can implement the actual code for your requirement as given below.
You can use array_search() function to get index of your value.
$a=array("a"=>"red","b"=>"green","c"=>"blue");
echo array_search("red",$a);
The array_search() function search an array for a value and returns the key.
Maybe I didn't understand you correctly but I assume that you are trying to detect the index or key for your desired id inside an array returned from an SQL query that is sorted by some other column like total.
So let us fetch records from the database with your query with a little change asArray() like this
$find = People::find()
->where(['c_id' => $c_id])
->orderBy('totals DESC, id DESC')
->asArray()
->all();
in the result, let us assume the People table returns you an array with the following dataset ordered by columns total and id DESC.
[
0 => [
'id' => 2 ,
'c_id'=>2,
'name' => 'John' ,
'age'=>18,
'totals'=>100,
],
1=>[
'id'=>1,
'c_id'=>55,
'name'=>'Bob',
'age'=>20,
'totals'=>80,
],
2=>[
'id'=>3,
'c_id'=>85,
'name'=>'Peter',
'age'=>15,
'totals'=>75,
]
];
Now if you look into \yii\helpers\ArrayHelper you will find ArrayHelper::getColumn().
Let us use this on the array we received from the query, I assume that you are searching $id inside the column id so we will first filter out the id column like below.
$idsArray = ArrayHelper::getColumn($find, 'id');
this will give us the ids in the following sequence which is in the same order as the initial result set.
[2,1,3]
then lets use the built-in php function array_search()
$key=array_search($yourId,$idsArray);
Hope this is what you are looking for.
Can you please help me extracting MySQL data in php array.
my sql:
SELECT count(*) as total, post_type as type FROM wp_posts group by post_type;
to php, like below:
<?php $total = array(5,7, .. , ..); $type = array('Page', 'Post', '..',..'); ?>
Array should come from database
Thanks :)
You can't get two separate arrays from single SQL query either you have to run the mysql query two times or Write a PHP code which gives you the desired result.
Your current query will give result as follow.
Array
(
[0] => Array
(
[total] => 5
[post_type] => Page
)
)
Now you have to traverse these array to create two separate arrays you want.
$total=array_column($result,'total');
$type = array_column($result,'post_type');
Above code will give you two separate arrays.
Thanks to Niet the Dark Absol for array_column, it looks more clean then traversing manually.
I want to calculate the avrage of a mysql result in PHP (I'm using CodeIgniter as framework).
My (model) code:
$query = $this->db->query('SELECT stars FROM feedback');
$res = $query->result_array();
$avrage = array_sum($res); // The impossible part
$avrage = round($avrage,0);
The result of the query looks like this: (print_r) Array ( [0] => Array ( [stars] => 5 ) [1] => Array ( [stars] => 3 ) )
I just want the '5' and '3' in a separate array, so array_sum() can do it's job. How do I do this?
Thanks.
You can do it in SQL directly using AVG()
SELECT avg(stars) as avg_stars
FROM feedback
Why not use AVG directly in your query?
'SELECT AVG(stars) as average FROM feedback'
The best way to do this would be to modify your SQL query, like this: SELECT AVG(stars) as stars_average FROM feedback. Then, after fetching the result set, you can do the following in your PHP code: $average = $res[0]['stars_average'];.
I'm having an issue where I call the result_array() function on n query object from in codeigniter:
$this->db->select(array('a','b','c'));
$query = $this->db->get('basic');
print_r($query->list_fields());
$test = $query->result_array();
print_r($query->list_fields());
When I run this code, or:
$query = $this->db->get('basic');
print_r($query->list_fields());
print_r($query->list_fields());
or:
$query = $this->db->get('basic');
$test = $query->result_array();
print_r($query->list_fields());
The second list_fields() function always returns an array size 0, the first returns the correct list of field names.
In the last example where there is only one list_fields() function, the array is again size zero.
Any guidance in this matter will be greatly appreciated. I need the list_fields() function to be accessible after I read the result_array().
Here is the result of the first block of code:
Array
(
[0] => site_id
[1] => institution
[2] => caller
[3] => call_complete
[4] => call_details
[5] => id
[6] => timestamp
)
Array
(
)
Thank you, for your help
That looks to be a bug in the database driver. For example, in CI_DB_mysqli_result:
public function list_fields()
{
$field_names = array();
while ($field = $this->result_id->fetch_field())
{
$field_names[] = $field->name;
}
return $field_names;
}
A subsequent call will return array() because the while loop seeks over all the fields and leaves the pointer at the end of the list.
However, in the result class, result_id is public, so you can use mysqli_result::field_seek:
$query = $this->db->get('basic');
var_dump($query->list_fields());
// this should be called before any call to list_fields()
$query->result_id->field_seek(0);
var_dump($query->list_fields());
However, this is bad practise, as this only works for mysqli; for mysql, you'll need this:
mysql_field_seek($query->result_id, 0);
and for mssql:
mssql_field_seek($query->result_id, 0);
The correct way to do this is really to fix it in the database drivers. See this pull request :-)