I'm using the DB class of CI framework. There're 5 rows queried out from the first line, and the second line printed 5, but why did the statement count($query->row_array())(or count($query->row_array(),1)) returned 11(the field number of table) and only one row filled in the result, rather than 5 rows?
$query = $this->db->query($SQL_BYLABEL, array($labelId, $orderby, (int)$m, (int)$n));
log_message('error', $query->num_rows()); // 5 rows
log_message('error', count($query->row_array())); // 11
$query->row_array() returns the data of one record as an array. So count($query->row_array() return the number of columns of the table.
Check the manual.
Related
This question already has answers here:
Select Last Row in the Table
(22 answers)
Closed 4 years ago.
public function addNewPost(Request $request)/****ADD new POST****/
{
$this->validate($request,['post_title'=>'required|min:4|max:100',
'post_description'=>'required|min:20|max:500'
]);
$user_name = Session::get('name');
$post_title = $request->input('post_title');
$post_description = $request->input('post_description');
$addPost = new AddNewPost(['user_name'=> $user_name, 'post_title'=> $post_title, 'post_description'=> $post_description]);
$addPost->save();
$addPost->post_id;
//$addPost = DB::table('userposts')->where(['user_name'=>$user_name ])->orderBy('post_id', 'desc')->get();
print_r($addAdmin->post_id); //This is printing nothing, i.e. blank.
}
post_id column in userposts table is auto incremented. I am trying to get the last post id of the user by user_name. I have seen some tutorials and also checked some questions over internet but unable to do what I am trying to get. Can anybody know how to do it. Thank you.
Try first() instead of get() in a query it might help you
$lastdata = DB::table('userposts')->where(['user_name'=>$user_name ])->orderBy('post_id', 'desc')->first();
print_r($lastdata);
Laravel has the last() method that you can use.
This is from the docs:
last()
The last method returns the last element in the collection that passes a given truth test:
collect([1, 2, 3, 4])->last(function ($value, $key) {
return $value < 3;
});
// returns 2
You may also call the last method with no arguments to get the last element in the collection. If the collection is empty, null is returned:
collect([1, 2, 3, 4])->last();
//returns 4
Here is the example for getting only the last id:
Model::pluck('id')->last();
DB::table('userposts')->last()->pluck('user_name') Is the fastest way .
Make sure to apply last() first to avoid unnecessary workload
Simple method which will not takes much processing is
DB::getPdo()->lastInsertId();
Hope this helps
You can also try
$addPost = new AddNewPost(['user_name'=> $user_name, 'post_title'=> $post_title, 'post_description'=> $post_description]);
$addPost->save();
$addPost->update();
print_r($addPost->post_id); //It will print id..
P.S second method is kind of redundant
Hope this helps
Please have a closer look at your print statement:
print_r($addAdmin->post_id);
The $addAdmin is not defined within the scope of your function. The best way to get the last row from your database:
DB::table('name_of_table')->last()->pluck('user_name')
Here is the documentation on using DB: https://laravel.com/docs/5.6/database
I'm making a functional test with laravel / Phpunit
What I expect is having 2 rows with championship_id = 123
But the content of each row may vary.
I only know how to check if a row exists :
$this->seeInDatabase('championship_settings',
['championship_id' => $championship->id,
]);
but I don't know how to check that there is 2 rows corresponding to criteria
Any idea how should I do it???
U can use seeNumRecords($expectedNumber, $table, $criteria).
<?php
$this->seeNumRecords(2, 'championship_settings', ['championship_id' => $championship->id]);
?>
param int $expectedNumber Expected number
param string $table Table name
param array $criteria Search criteria [Optional]
See http://codeception.com/docs/modules/Db#seeNumRecords
I'm new with Zend Framework 2 and ZendSearch Lucene.
My database table has three columns with integers, the first one is for the id.
In the second is the publish value (1 to 3), in the third is the category value (1 to 5).
The Table looks like this:
|id|publish|category|
|1|1|1|
|2|1|2|
|3|1|3|
|4|2|3|
|5|2|4|
I tested this with the following queries:
"publish:1" Return the correct id's 1,2,3;
"publish:2" Return the correct id's 4,5;
"publish:3" Return the incorrect id's 1,2,3,4,5; The result should be empty.
"publish:1 AND category:1" Return the correct id 1;
"publish:1 AND category:3" Return the correct id 3;
"publish:1 AND category:4" Return the correct empty result;
"publish:1 AND category:5" Return the incorrect id's 1,2,3; The result should be empty.
When a number doesn't exist, the result is not empty, it contains all rows.
Is there any option, that the result is empty when the number doesn't exist?
The default encoding is UTF-8:
\ZendSearch\Lucene\Search\QueryParser::setDefaultEncoding('UTF-8');
\ZendSearch\Lucene\Analysis\Analyzer\Analyzer::setDefault(new \ZendSearch\Lucene\Analysis\Analyzer\Common\Utf8Num\CaseInsensitive());
The id is unindexed, publish and category are keywords.
I think I found the answer.
When I build the query with the following code the query is "+(publish:1) +(category:1)" and this works.
$query = new \ZendSearch\Lucene\Search\Query\Boolean();
$termPublish = new \ZendSearch\Lucene\Index\Term(1, 'publish' );
$subqueryPublish = new \ZendSearch\Lucene\Search\Query\Term($termPublish);
$query->addSubquery($subqueryPublish, true); // required
$termCategory = new \ZendSearch\Lucene\Index\Term(1, 'category' );
$subqueryCategory = new \ZendSearch\Lucene\Search\Query\Term($termCategory);
$query->addSubquery($subqueryCategory, true); // required
Im trying to update all records in the DB, there is no key and no where clause.
But im getting an error saying I must specify a where clause.
$data = array('views' => 0);
$this->db->update_batch('table_places', $data);
Simply using
$data = array('views' => 0);
$this->db->update('table_places', $data)
will update all the records in the table_places database for you.
update_batch() is used for updating multiple rows in your table with different data.
Current situation
I have two tables in my database, one for posts, and one for ratings. These are linked with a relation in the MySQL so that one post may have 0, 1 or multiple ratings, but one rating can only be applied to one post.
When I fetch a list of posts, I also want to get ratings, but without having to make a separate call to the database for each post in the foreach loop.
To do this I have attempted to use an SQL query to fetch all posts with a LEFT JOIN on ratings so that it will return a result like this:
statusId|statusBody|rating
-----------------------------
1, post1, 0
1, post1, 1
2, post2, 0
3, post3, 1
3, post3, 1
The SQL works fine, and I get the data I ask for.
Ideally what I am trying to achieve now is to turn this table into a collection of objects, with each object storing the post information as well as a value depending on it's total ratings.
After using PDO to return the data result, this is the code I am using to map the data:
Code Logic
The logic of my code goes like this:
Get all statuses joined with ratings table
Create empty output array
Loop through PDO result
{
Create loop specific temp array
Push first row of result into temp array
Remove row from PDO result
Loop through PDO result for objects with matching statusId
{
If row matches statusId, add to temp buffer and remove from PDO result
}
Take first row of buffer and create status object
Loop through objects in temp array to calculate ratings and add onto above status object
Clear temp buffer
Add status object to output array
}
return output array
Actual Code
try
{
$result = $pdo->query($sql);
//if($result == false) return false;
$statuses = $result->fetchAll(PDO::FETCH_CLASS, 'status');
}
catch (PDOException $e)
{
return FALSE;
}
if (!$result) {
return FALSE;
}
//create empty output array to be filled up
$status_output = array();
//loop through all status
foreach($statuses as $s1key => $s1value)
{
//initialise temporary array;
$status_temp_buffer = array();
//create temp array for storing status with same ID in and add first row
array_push($status_temp_buffer, $s1value);
//remove from primary array
unset($statuses[$s1key]);
//loop through array for matching entries
foreach($statuses as $s2key => $s2value)
{
//if statusId matches original, add to array;
if($s2value->statusId == $s1value->statusId)
{
//add status to temp array
array_push($status_temp_buffer, $s2value);
//remove from primary array
unset($statuses[$s2key]);
}
//stop foreach if statusId can no longer be found
break;
}
//create new status object from data;
$statObj = $status_temp_buffer[0];
//loop through temp array to get all ratings
foreach($status_temp_buffer as $sr)
{
//check if status has a rating
if($sr->rating != NULL)
{
//if rating is positive...
if($sr->rating == 1)
{
//add one point to positive ratings
$statObj->totalPositiveRatings++;
}
//regardless add one point to total ratings
$statObj->totalAllRatings++;
}
}
//clear temporary array
$status_temp_buffer = NULL;
//add object to output array
array_push($status_output, $statObj);
}
Problem
The problem I am coming up against with this code is that although the ratings are fine, and it correctly calculates the ratings total for each post, it still shows duplicates where a post has more than one rating.
Any help with this would be greatly appreciated,
Thanks
As i understood it, the goal is to get the total rating of each Post entry. Instead of manually looping over each and every rating, there are two other path you could take:
compute the total in the query:
SELECT SUM(rating) AS total , .. FROM Posts LEFT JOIN .... GROUP BY statusID
You will receive a list of Post entries, each already with total rating calculated. This is a very good solution if you have a lot of writes to to the Ratings table, and much less reads.
the other way is to break the table normalization, but to increase read performance. What you would have to do is to add another column in the Posts table: total_rating. And have an TRIGGER on INSERT in the Ratings table, which changes the Posts.total_rating accordingly.
This way has a benefit of simplifying the request of Posts. At the same time Ratings table can now be use to ensure that total_rating has been calculated correctly, or to recalculate the value, if there are some large changes in the ratings: like banning of user, which results in removing all ratings made by this user.