count get collection and count query giving different results - laravel

So i am trying to get distinct collections like this
$data = DB::table('project_1_data')->distinct('Farmer_BankVerificationNumber_Farmer')->get();
But when i do a count($data) I get 1600 but when i run
$data = DB::table('project_1_data')->distinct('Farmer_BankVerificationNumber_Farmer')->count();
I get 1440. This is weird as i only want collection with distinct field 'Farmer_BankVerificationNumber_Farmer'. How do i write the query correctly?

It's because you're asking your query to count the distinct values in the wrong place.
You need to tell your count parameter what field you would like to count on. So you'll basically ask the query to get the database information, separate the distinct values and then count how many of a specific field are distinct.
Your finished query should look like this:
$data = DB::table('project_1_data')
->distinct()
->count('Farmer_BankVerificationNumber_Farmer');

Related

How to get list of ids from pagination query of the current page?

I have 1 pagination query for every:
$pagination_query = Table1::...->paginate(100);
then I have a second query that needs to use the list of ids from the pagination query:
$second_query = Table2::whereIn('id', $list_of_ids_from_pagination_query);
How can I get the list of ids only from the paginated page so that I get 100 ids and not thousands of ids which will end up in too many bound variables error?
Ty!
You can use something like this .
$ids = Table1::...->paginate(100)->pluck('id');
$second_query = Table2::wherein('id', $ids);

How I get data like 0 to 50 and 51 to 100 in laravel

I want to get data from database with range like 0 to 50 and 51 to 100, this is possible? if possible please talk me how to do that.
$users = User::all();
I am not able to get clearly what do you want. But I have provided some examples below that might work for you.
$users = DB::table('users')
->whereBetween('id', [1, 50])
->get();
Also try skip and take.
You may use the skip and take methods to limit the number of results returned from the query or to skip a given number of results in the query:
$users = DB::table('users')->skip(50)->take(50)->get();
Alternatively, you may use the limit and offset methods. These methods are functionally equivalent to the take and skip methods, respectively:
$users = DB::table('users')
->offset(50)
->limit(50)
->get();
Hope this helps!
There are a number of options available to you. If you're looking to obtain a working data set of x results at a time and not concerned about the id of the results, then one of the following might be of use:
Pagination
Chunking results
Both of the above will allow you to define the size/number of records returned for your data set.
If you're looking to return records between specific id values, then you'll want to use something like whereBetween on your database queries. The whereBetween clause can be used in conjunction with the pagination and chunking.

Efficient way to query database with multiple conditions in laravel

Is it possible to make this a single query?
$yl_min = DB::connection($this->db2)->table('historical')
->where([['slug','=',$crypto_id],['low_usd','!=', null]])
->whereBetween('created_time',[$this->range_1y,$this->hislatest])
->min('low_usd');
$yl = DB::connection($this->db2)->table('historical')
->select('id','coin','low_usd','created_time','created_at')
->where([['slug','=',$crypto_id],['low_usd',$yl_min]])
->whereBetween('created_time',[$this->range_1y,$this->hislatest])
->first();
I've tried this but no luck:
$yl = DB::connection($this->db2)->table('historical')
->select('id','coin','created_time','created_at',DB::raw('SELECT MIN(low_usd) as low_usd'))
->where([['slug','=',$crypto_id],['low_usd','!=', null]])
->whereBetween('created_time',[$this->range_1y,$this->hislatest])
->first();
After looking at your query code, I found the two query condition is same, and you just want to get min low_usd record,
I think you can just use the multiple condition and ORDER BY low_usd ASC, then take the first one:
$yl = DB::connection($this->db2)->table('historical')
->where([['slug','=',$crypto_id],['low_usd','!=', null]])
->whereBetween('created_time',[$this->range_1y,$this->hislatest])
->orderBy('low_usd','asc')
->select('id','coin','low_usd','created_time','created_at')
->first();
After this, if you want to make this query more efficient,
you need to add index on slug, low_usd, created_time

CodeIgniter Count Records for Query that Excludes Limit Condition

I want to do two things in one query: use the limit() function, but also get the total number of records as a record count for the query, as if the limit wasn't used. So, if there are 21 total records that meet the conditions like '%Gregory%', I would like that value returned, even though I'm using a limit(10,0).
Here's my code:
$data['recordcount'] = $this->db->count_all_results('assets');
$this->db->limit(10, 0);
if(isset($data['order'])){
$query = $this->db->select('*')->from('assets')->or_like($array)->order_by($column, $data['order'])->get();
}
The problem is that $data['recordcount'] in the first line returns all records. I want it to return all records that meet the query condition in the 4th line, but without the limit found in the 2nd line.
Normally count_all_results() clears the select statement when run. But by setting the second parameter to FALSE the statement is retained.
I think this will work for you.
$this->db->select('*')->from('assets')->or_like($array);
$data['recordcount'] = $this->db->count_all_results('assets', FALSE);
$this->db->limit(10, 0);
if(isset($data['order']))
{
$this->db->order_by($column, $data['order']);
}
$query = $this->db->get();
You can achieve SQL_CALC_FOUND_ROWS before the asterisk (*) like this:
$this->db->select('SQL_CALC_FOUND_ROWS *')->from('assets')..etc
This will calculate the number of rows that would be returned without the LIMIT condition.
Immediately after that you can select the FOUND_ROWS() like this:
$this->db->select('FOUND_ROWS()')->get();
This will return you the number you are looking for.
For more information refer to this page
enter link description here

Laravel Eloquent - distinct() and count() not working properly together

So I'm trying to get the number of distinct pids on a query, but the returned value is wrong.
This is what I try to do:
$ad->getcodes()->groupby('pid')->distinct()->count()
what returns the value "2", while the value it should return, should be "1".
As a workaround, I'm doing this:
count($ad->getcodes()->groupby('pid')->distinct()->get())
what works fine and returns "1"
Is there any rule where count and distinct cannot be on the same query? I find the workaround kind of "heavy", I would like to make the original query work :(
The following should work
$ad->getcodes()->distinct()->count('pid');
A more generic answer that would have saved me time, and hopefully others:
Does not work (returns count of all rows):
DB::table('users')
->select('first_name')
->distinct()
->count();
The fix:
DB::table('users')
->distinct()
->count('first_name');
Anyone else come across this post, and not finding the other suggestions to work?
Depending on the specific query, a different approach may be needed. In my case, I needed either count the results of a GROUP BY, e.g.
SELECT COUNT(*) FROM (SELECT * FROM a GROUP BY b)
or use COUNT(DISTINCT b):
SELECT COUNT(DISTINCT b) FROM a
After some puzzling around, I realised there was no built-in Laravel function for either of these. So the simplest solution was to use use DB::raw with the count method.
$count = $builder->count(DB::raw('DISTINCT b'));
Remember, don't use groupBy before calling count. You can apply groupBy later, if you need it for getting rows.
You can use the following way to get the unique data as per your need as follows,
$data = $ad->getcodes()->get()->unique('email');
$count = $data->count();
Hope this will work.
I had a similar problem, and found a way to work around it.
The problem is the way Laravel's query builder handles aggregates. It takes the first result returned and then returns the 'aggregate' value. This is usually fine, but when you combine count with groupBy you're returning a count per grouped item. So the first row's aggregate is just a count of the first group (so something low like 1 or 2 is likely).
So Laravel's count is out, but I combined the Laravel query builder with some raw SQL to get an accurate count of my grouped results.
For your example, I expect the following should work (and let you avoid the get):
$query = $ad->getcodes()->groupby('pid')->distinct();
$count = count(\DB::select($query->toSql(), $query->getBindings()));
If you want to make sure you're not wasting time selecting all the columns, you can avoid that when building your query:
$query = $ad->select(DB::raw(1))->getcodes()->groupby('pid')->distinct();
I came across the same problem.
If you install laravel debug bar you can see the queries and often see the problem
$ad->getcodes()->groupby('pid')->distinct()->count()
change to
$ad->getcodes()->distinct()->select('pid')->count()
You need to set the values to return as distinct. If you don't set the select fields it will return all the columns in the database and all will be unique. So set the query to distinct and only select the columns that make up your 'distinct' value you might want to add more. ->select('pid','date') to get all the unique values for a user in a day
Based on Laravel docs for raw queries I was able to get count for a select field to work with this code in the product model.
public function scopeShowProductCount($query)
{
$query->select(DB::raw('DISTINCT pid, COUNT(*) AS count_pid'))
->groupBy('pid')
->orderBy('count_pid', 'desc');
}
This facade worked to get the same result in the controller:
$products = DB::table('products')->select(DB::raw('DISTINCT pid, COUNT(*) AS count_pid'))->groupBy('pid')->orderBy('count_pid', 'desc')->get();
The resulting dump for both queries was as follows:
#attributes: array:2 [
"pid" => "1271"
"count_pid" => 19
],
#attributes: array:2 [
"pid" => "1273"
"count_pid" => 12
],
#attributes: array:2 [
"pid" => "1275"
"count_pid" => 7
]
$solution = $query->distinct()
->groupBy
(
[
'array',
'of',
'columns',
]
)
->addSelect(
[
'columns',
'from',
'the',
'groupby',
]
)
->get();
Remember the group by is optional,this should work in most cases when you want a count group by to exclude duplicated select values, the addSelect is a querybuilder instance method.
Wouldn't this work?
$ad->getcodes()->distinct()->get(['pid'])->count();
See here for discussion..
Distinct do not take arguments as it adds DISTINCT in your sql query, however, you MAY need to define the column name that you'd want to select distinct with. Thus, if you have
Flight->select('project_id')->distinct()->get() is equialent to SELECT DISTINCT 'project_id' FROM flights and you may now add other modifiers like count() or even raw eloquent queries.
Use something like this
DB::table('user_products')->select('user_id')->distinct()->pluck('user_id')->toArray();
This was working for me so
Try This:
$ad->getcodes()->distinct('pid')->count()
try this
$ad->getcodes()->groupby('pid')->distinct()->count('pid')

Resources