Laravel groupBy with select multiple field - laravel

I can select country and groupBy the result as following with an alias total :
Data::select('country', DB::raw('count(*) as total'))
->groupBy('country')
->get();
The above code works well.
Here I can select only country filed, But I need to select aslo name, positions field, How can I select multiple field here?

You have to use like below settings and change code.
Open config/database.php
Find strict key inside mysql connection settings
Set the value to false
Use code below like
ModelName::groupBy('country')
->selectRaw('count(*) as total, country, name, positions')
->get()

First, you need to specify what error/exception you're getting but you can add additional column by doing
DB::table('table_name')->select([DB::raw('count(*) as total'), 'name', 'positions', 'country'])
->groupBy('country')
->get());
it is also likely you get an access violation exception which requires you to change sql_mode

Related

Laravel Eloquent join if column null

I have two tables users/invoices in 1:n relation. When someone creats an invoice it saves the user_id. Also it's possible (optional) to set a manager (column: project_management_user_id). If there is no manager set (NULL), I want to get the user, who created the record. So for now I have this query. It gives me all invoices with the manager (but not that ones with manager = null.
$query = Invoice::join('users', 'invoices.project_management_user_id', '=', 'users.id')
->select('users.name as name', 'users.color as color', DB::raw("count(invoices.id) as count"))
->get();
Is it possible to add some if-clause like "if project_management_user_id is null, take the user_id"? I read about the whereNull() function, but it filters my whole query
Use leftJoin instead of join in the query.

Parameters in Laravel Eloquent pagination

$articles = Article::paginate(10, ['*'], 'pag');
What does the second parameter [*] above do?
The first parameters is the number of resources to be displayed by page.
The third parameter is the name of the query that will appear in the URL (i.e, "pag?=3").
What about "[*]"? I've used it for a long time without knowing what it does.
Don't tell me to search in Laravel Docs because I already did this and didn't find anything useful.
2nd parameter is select() method from Illuminate\Database\Eloquent\Builder which means select * from table ... limit 15.
You can specify which columns you want select from database.
For exaple $users->paginate(10, ['id', 'name']); -> select id, name from users ... limit 10
FYI: ['*'] is not fully qualified!
If you are using join in your select, it might be a problem if the columns with the same name are present in both tables. For example uuid, etc ...
In this case you should specify table name in select: ['table_name.*'] -> select table_name.* from table_name ... limit 15

How to query multiple where in laravel

I have a query that gets all the message between two id (user_id and to_user_id). I want to select all the query all the message of user in the two tables.
I have already made two where and it doesn't seem to work. It is just returning null.
$last_message = DB::table('messages')
->select('content')
->where('user_id','=',Auth::user()->id)
->where('to_user_id','=',Auth::user()->id)
->orderBy('updated_at', 'desc')
->first();
I expect the output of all the message of user
You should check on this Auth::user()->id,
to see if it has a value or not. Also check on the datatype between table field and data source in query builder.

In Laravel Eloquent, how do I reference primary query in subquery

I have a model User that has many Orders. Orders have many products, with the pivot table order-product. I don't want to preload and iterate through the orders if at all possible.
I need to return users where
signed_date === true on User
order_date on Order is after signed_date on User
order-product shows product hasn't been paid
I am failing on number 2.
In the following code, the first query within whereHas is wrong. I don't know how to reference the signed date of the user from within the where has. If I was iterating through users in a collection I could do something like ($query) use $user, but how do I do this without preloading all the users?
return User::whereNotNull('signed_date')
->whereHas('orders', function ($query) {
$query->where('order_date', '<=', 'user.signed_date');
$query->whereHas('products', function ($q) {
$q->where('paid', false);
});
})
->get(['id','fname','lname', 'title', 'signed_date']);
I would like to use eloquent if possible. If that is not possible, I would be happy for tips in solving this problem using the query builder/sql.
The Eloquent query builder has a special function called whereColumn('a', '<=', 'b') to compare columns instead of a column against a value. Using this function instead of a normal where() is necessary because of the way the query builder builds the actual query. You need to let the query builder know that you are going to pass a column name instead of a value for proper escaping and formatting of the query string.
Anyway, it seems you can also pass column names prefixed with a table name to the function, allowing you to compare columns across tables:
$query->whereColumn('orders.order_date', '<=', 'users.signed_date')
This works because you are using whereHas() in your query. Your query basically gets translated to:
SELECT id, fname, lname, title, signed_date
FROM users
WHERE signed_date NOT NULL
AND EXISTS (
SELECT 1
FROM orders
WHERE orders.order_date <= users.signed_date
AND EXISTS (
SELECT 1
FROM products
WHERE paid = 0
)
)
It might actually be not necessary at all to use the table name together with the column name in whereColumn(). But in case you'll ever add a column named the same on another table, the query might break - so IMHO it is good practice to use the table name in custom queries.
By the way, the reason this will not work together with with('relationship') is that this function results in an additional query and you obviously cannot compare columns across queries. Imagine the following:
Order::with('user')->take(5)->get();
It will be translated into the following:
SELECT *
FROM orders
LIMIT 5
SELECT *
FROM users
WHERE id IN (?, ?, ?, ?, ?)
where the five ? will be the user_ids of the orders. If the first query returns multiple rows with the same user_id, the amount of rows fetched from the users table gets reduced of course.
Note: All the queries are only examples. Might be that the query builder builds different queries based on the database type and/or escapes them differently (i.e. column names in backticks).

Select rows having 2 columns equal value in laravel Query builder

I want to write a query which selects rows where 2 attributes from 1 entity have equal value.
This would be an example of doing this in raw SQL:
Select * from users u where u.username = u.lastname
Does laravel have any methods that take 2 column names as parameters and return the matching results?
What you need is a DB::raw expression:
DB::table('users')
->where('username', '=', DB::raw('lastname'))
->get();
The only thing DB::raw actually does is to tell the query interpreter not to treat 'lastname' like any other string value but just interpolate it in the SQL as it is.
http://laravel.com/docs/queries#raw-expressions
In Laravel 5, there's now whereColumn for this, for cleaner code:
Users::whereColumn('username', 'lastname')->get();

Resources