Laravel - orWhere causes wrong results - laravel

I have the following query
Event::where('event_name', $event_id)
->orWhere('id', $event_id)->first();
The $event_id can be a alpha-numeric string (event_name) or an integer (id - primary key). The orWhere statement takes priority over the where statement everytime unless the orWhere statement fails.
For example, the following query gets an event with id = 601, eventhough there is an event that has an event_name = 601a35e0ebee30 with id = 1070.
Event::where('event_name', "601a35e0ebee30")
->orWhere('id', "601a35e0ebee30")->first();
Shouldn't the where statement take precedence over orWhere? Am I missing something?
Also how come a alpha-numeric string work with the primary key (id) which is an unsigened integer?
P.S. When I use Event::find("601a35e0ebee30"), it returns an event with id of 601

use nested array
Event::where([['event_name', $event_id]])->orWhere([['id', $event_id]])->first();

Please try this one.
Event::where(function($query) use ($event_id){
$query->where('event_name', $event_id);
$query->orWhere('id', $event_id);
})->first();

Related

Laravel eloquent query with nested whereDate

I currently have a table called operators
The columns are:
id, user_id, item_clicked, created_at, updated_at
I can confirm on one of these it has today's update_at
2019-08-05 showing as today.
This is a relational table.
operators belongs to users.
I'm attempting to get operators of users whereDate is today.
My code is:
$ordersClicked = User::with('operators')
->whereDate('updated_at', \Carbon\Carbon::today())
->get();
This returns an empty array.
Testing this works so I know the data I need is there.
$ordersClicked = User::with('operators')
->get();
$operator = Operator::whereDate('updated_at', \Carbon\Carbon::today())->get();
Any idea what I'm doing wrong?
According to the docs https://carbon.nesbot.com/docs/ Carbon::today() returns Y-m-d H:i:s, if used like you are doing in a where clause and the database stores the value in Y-m-d format.
Why don't you try this:
$ordersClicked = User::with('operators')
->whereDate('updated_at', \Carbon\Carbon::today()->format('Y-m-d'))
->get();
if that doesn't work; then it is possible the eloquent is applying the where clause on updated_at on the User table, instead of Operator. Did you mean to do something like this:
$ordersClicked = User::with(['operators' => function($query) {
$query->where('updated_at', \Carbon\Carbon::today()->format('Y-m-d'))
}])->get();
i.e. filter on the eager loaded collection? if this is what you intended, what will happen is it will return all users and only some operators that has the updated_at matching the criteria will have values, where others will be null.
Wouldn't it be better to reverse the query? i.e. make sure Operator has a belongsTo relationship on User model and query the data like this:
$operator = Operator::whereDate('updated_at', \Carbon\Carbon::today())
->with('user')
->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;

Laravel - When to use ->get()

I'm confused as to when ->get() in Laravel...
E.G. DB::table('users')->find(1) doesn't need ->get() to retrieve the results, neither does User::find(1)
The laravel docs say "...execute the query using the get or first method..."
I've read the Fluent Query Builder and Eloquent docs but don't understand when the usage of get() is required...
Thanks for the help
Since the find() function will always use the primary key for the table, the need for get() is not necessary. Because you can't narrow your selection down and that's why it will always just try to get that record and return it.
But when you're using the Fluent Query Builder you can nest conditions as such:
$userQuery = DB::table('users');
$userQuery->where('email', '=', 'foo#bar.com');
$userQuery->or_where('email', '=', 'bar#foo.com');
This allows you to add conditions throughout your code until you actually want to fetch them, and then you would call the get() function.
// Done with building the query
$users = $userQuery->get();
For find(n), you retrieve a row based on the primary key which is 'n'.
For first(), you retrieve the first row among all rows that fit the where clauses.
For get(), you retrieve all the rows that fit the where clauses. (Please note that loops are required to access all the rows or you will get some errors).
find returns one row from the database and represent it as a fluent / eloquent object. e.g. SELECT * FROM users WHERE id = 3 is equivalent to DB::table('users')->find(3);
get returns an array of objects. e.g. SELECT * FROM users WHERE created_at > '2014-10-12' is equivalent to DB::table('users')->where('created_at', '>', '2014-10-12')->get() will return an array of objects containing users where the created at field is newer than 4014-10-12.
The get() method will give you all the values from the database that meet your parameters where as first() gets you just the first result. You use find() and findOrFail() when you are searching for a key. This is how I use them:
When I want all data from a table I use the all() method
Model::all();
When I want to find by the primary key:
Model::find(1)->first();
Or
Model::findOrFail(1)->first();
This will work if there is a row with a primary key of one. It should only retrieve one row so I use first() instead of get(). Remember if you deleted the row that used key 1, or don't have data in your table, your find(1) will fail.
When I am looking for specific data as in a where clause:
Model::where('field', '=', 'value')->get();
When I want only the first value of the data in the where clause.
Model::where('field', '=', 'value')->first();
Basically what you need to understand is that get() return a collection(note that one object can be in the collection but it still a collection) why first() returns the first object from the result of the query(that is it returns an object)
#Take_away
Get() return a collection first() return an object
You can use get() method with latest() method to get the latest record that were recently added to your table
For example
$user=Student::latest()->get();
return all the data in descending order

Doctrine: how to return the row count of a records in a groupby statement

Seems like such a simple thing, but I can't get my query to return the number of records in a group. Here's my statement:
public function getGroupCount($user_id)
{
$q = Doctrine_Query::create()
->select('ss.*')
->from('SalarySurvey ss')
->where('ss.user_id=?', $user_id)
->groupBy('created_at')
->execute();
return $q->rowCount();
}
rowCount() does not work in the above query.
It might also be helpful to know that this is being used in a foreach statement.
As CappY suggested, this is not possible in Doctrine 1.2, as far as I know. As a work-around, I was able to finally get a count for each grouping by adding another field to the table and setting that field the same for each group at save time. Then I changed my query to pull that field and just did a simple:
$q->count();
Never work with Doctrine 1.2, but can't U use php's count function or SELECT COUNT() AS 'cnt' ?
return count($q);

Resources