How to combine and & or operators in grocery crud - codeigniter

I am using codeigniter and grocerycrud, I want to set a table with grocerycrud in this way:
SELECT * FROM `dashboard`.`medidas_ludlum`
where FK_ludlum='190.26.88.131'
and date>= '2014-03-04 09:40:00'
and date<= '2014-03-05 09:40:00'
and (error_code=1 or audio_status=1);
I tried to do that in this way:
$uno='1';
$crud2 = new grocery_CRUD();
$crud2->set_theme('datatables');
$crud2->where('FK_ludlum',$ludlum_id);
$crud2->where('date>=',$fechainicio);$crud2->where('date<=',$fechafin);
$crud2->where('error_code =',$uno);
$crud2->or_where('audio_status =',$uno);
$crud2->set_table('medidas_ludlum');
$crud2->columns('measurement', 'fecha', 'audio_status', 'high_alarm_status', 'low_alarm_status','over_range_status','monitor_status','error_code');
$crud2->set_language("spanish");
$crud2->unset_add();$crud2->unset_delete();$crud2->unset_edit();$crud2->unset_read();
$data['crud2'] = $crud2->render();
However it's not giving the right results, for example I am getting rows that have a date out of the range, is there a way to get that CRUD set up?

Grocery curd is also using codeigniter's active record so you can write your where() with grouped conditions as below,no need to use or_where() function
$crud2->where('(error_code ='.$uno.' OR audio_status ='.$uno.')',null,FALSE);
or
$crud2->where('(error_code =1 OR audio_status =1)',null,FALSE);
The problem in your query is when you use or_where() function it produces where clause as and error_code=1 or audio_status=1 and using approach that i have provide will give you the where clause as and (error_code=1 or audio_status=1) a grouped condition
API and Functions list

Related

Paginate count(*) query issue

Laravel Version: 8.0
PHP Version: 7.3.0
Database Driver & Version: MySQL 5.7.34
Describe the Bug
When I use paginate for pagination the data it call the count( * ) query every time even I pass the column name like count(['id']), and the count( * ) query scan all row in the table.
Table name is users and it has 45 column
Route
Route::get("users", "UsersController#index");
Controller
namespace App\Http\Controllers\Api\V1;
class UsersController extends Controller
{
public function index()
{
return User::paginate(10 , ['id']);
}
}
Call users route
Telescope showing me that two queries
Actual result
Expected result
Steps To Solution:
The following image shows that I had done changes as per our functionality, It will take the first column name from the passed in the paginate method array of $columns params and that query does not scan all columns of the users tables.
Final Results:
I have tired to solving this issue any other way or idea then please let me know
Its not recommended to ever touch the vendor files, you can always just override the functionality inside of your model, you can also pass in the columns to override the getCountForPagination() and you can also pass the columns to simplePaginate() that doesn't invoke any counting!
In order to optimize the query to count and paginate, you can do it like this:
//We will call the query on the model
$program = Program::query()->getQuery();
//count the query by specific columns
$thePaginationCount = $program->getCountForPagination(['id']);
//paginate the results using simplePaginate and select the columns we want:
$thePaginatedProgram = $program->simplePaginate(10, ['id', 'name']);
return 'test: '.$thePaginatedProgram;
Will result like this:
select count(`id`) as aggregate from `programs`
select `id`, `name` from `programs` limit 11 offset 0
As you can see it will only load what we specify and its very efficient!
Final Note:
If you just want to paginate without the count, you can always call Model::simplePaginate($amount, [$columns...])
https://laravel.com/docs/9.x/pagination#simple-pagination

Livewire and Eloquent - Sums of multiple columns in filtered collection

quite a noob in Laravel and Livewire, I guess if there is a better way to accomplish what I have here:
I have some checkboxes in a Livewire view that allow the user to dynamically choose how to filter the data being shown in a HTML table.
On the controller I have an eloquent query that retrieves a subset of the records in the db whenever a checkbox changes state.
Like this (I tried to simplify the structure):
$filtered_items = Item::select('item_color', 'item_quantity', 'item_value')
->whereIn('item_color', [ /* array controlled by checkboxes values in view */ ])
->get();
I need to also show the sums of some columns for that specific filter setup.
As I don't want to make new queries, I try to work on the already available collection with a ->sum() for each column I want to sum:
$sums['item_quantity'] = $filtered_items->sum('item_quantity');
$sums['item_value'] = $filtered_items->sum('item_value');
It works as intended, as I have an array with the sums, but I was wondering if there is a better way to do this, or even write a function to get more columns sum at once, maybe passing an array.
Thanks for any idea or link!
Here is an example of a single query for all sums (two in this example)
$filtered_items = \DB::table('items')
->selectRaw('SUM(item_quantity) as sum_quantity, SUM(item_value) as sum_value')
->whereIn('item_color', [ /* array controlled by checkboxes values in view */ ])
->first();
The advantage is that it will return one entry/row instead of a collection of all the items which is way faster.

Laravel retrieve only specific fields from each item of collection

I may be missing something extremely trivial, but is it possible to retrieve specific columns/fields from models when grabbing a collection rather then returning the entire item's fields?
Here is my query:
$items = Items::where('visible', true)->take(10)->get();
This obviously returns each item in there entirety, including unique id's, and other fields i dont want to be fetched... how can i refine this query to just select specific fields from the models?
Laravel Query Builder get() function receives array of columns which you need to fetch.
$items = Items::where('visible', true)->take(10)->get(['column_1', 'column_2']);
Use select() method to do this:
$items = Items::select(['column_1', 'column_2']'])->where('visible', true)->take(10)->get();
Source: Latavel Database Query Builder
Laravel Query Builder gives a huge flexibility to write this types of query.
You can use select(), get(), all() methods.
Items::where('visible', true)->take(10)->get('col_1', 'col_2');
OR
Items::select('col_1', 'col_2')->where('visible', true)->take(10)->get();
Items::select(['col_1', 'col_2'])->where('visible', true)->take(10)->get();

Laravel query builder - Select elements unique or null on specific column

I have a model Form for table forms. There is a column called guid which can be null, or contain some sort of grouping random hash.
I need to select all forms that have column guid either null or unique in current search. In other words, for repeating guid values in current search I select only first occurence of every guid hash.
I tried:
$results = App\Form::where(... some where clauses .. ).groupBy('guid')
and it's almost ok, but for all rows, where guid == NULL it groups them and selects only one (and I need all of them).
How can I get the unique or null rows either by building proper SQL query or filtering the results in PHP?
Note: I need my $results to be an Illuminate\Database\Eloquent\Builder instance
EDIT:
I fount out that SQL version of query I need is:
SELECT * FROM `forms` WHERE .... GROUP BY IFNULL(guid, id)
What would be equivallent query for Laravel's database query builder?
UPDATE: Using DB::raw
App\Form::where(... conditions ...)
->groupBy(DB::raw("IFNULL('guid', 'id')"));
Or the another way could be:
You can also use whereNotNull, whereNull & at last merge both the collections using merge() like this:
First get the results where guid is grouped by (excluding null guid's here):
$unique_guid_without_null = App\Form::whereNotNull('guid')->groupBy('guid')->get();
Now, get the results where guid is null:
$all_guid_with_null = App\Form::whereNull('guid')->get();
and at last merge both the collections using merge() method:
$filtered_collection = $unique_guid_without_null->merge($all_guid_with_null);
Hope this helps!
For your edited question, you can use raw() as;
->groupBy(DB::raw("IFNULL('guid', 'id')"))
So your final query will be as:
$results = App\Form::where(... some where clauses .. )
->groupBy(DB::raw("IFNULL('guid', 'id')"));
By above query, your $results will be an instance of Illuminate\Database\Eloquent\Builder.

Select one column with where clause Eloquent

Im using Eloquent. But I'm having trouble understanding Eloquent syntax. I have been searching, and trying this cheat sheet: http://cheats.jesse-obrien.ca, but no luck.
How do i perform this SQL query?
SELECT user_id FROM notes WHERE note_id = 1
Thanks!
If you want a single record then use
Note::where('note_id','1')->first(['user_id']);
and for more than one record use
Note::where('note_id','1')->get(['user_id']);
If 'note_id' is the primary key on your model, you can simply use:
Note::find(1)->user_id
Otherwise, you can use any number of syntaxes:
Note::where('note_id', 1)->first()->user_id;
Note::select('user_id')->where('note_id', 1)->first();
Note::whereNoteId(1)->first();
// or get() will give you multiple results if there are multiple
Also note, in any of these examples, you can also just assign the entire object to a variable and just grab the user_id attribute when needed later.
$note = Note::find(1);
// $user_id = $note->user_id;

Resources