How can I make this query in Laravel, using Eloquent ORM?
select * from posts p order by ( select count(*) from likes where flag = 'c' and p.id = post_id ) Desc limit 3
I have this relationship in my models
Post.php
public function likes(){
return $this->hasMany('Like', 'post_id');
}
Like.php
public function post(){
return $this->belongsTo('Post', 'post_id');
}
Thanks! :)
You may try something like this:
$posts = Post::leftJoin('likes', function($join) {
$join->on('posts.id', '=', 'likes.post_id')->where('flag', '=', 'c');
})
->select('posts.*', 'likes.post_id', DB::raw('count(likes.post_id) as pCount'))
->groupBy('post_id')
->orderBy('pCount', 'desc')
->take(3)
->get();
Related
How do I join Category if Subcategory is Null. The below query builder is working for Category that have Subcategory too, but not working for those category where Subcategory is Null.
public function Index(){
$post = DB::table('posts')
->join('categories', 'posts.category_id', 'categories.id')
->join('subcategories', 'posts.subcategory_id', 'subcategories.id')
->select('posts.*', 'categories.category_en', 'subcategories.subcategory_eng')
->orderBy('id', 'desc')->paginate(5);
return view('backend.post.index', compact('post'));
}
Use leftJooin to subcategories. See more about Left Join in Laravel.
As you didn't shared table schema of above tables to understand the relationship between them. If subcategories table have column category_id which relate subcategory to it parent than follow the below code:
->leftJoin('subcategories', 'categories.id', 'subcategories.category_id')
Replace above written line of code in your function like I did below:
public function Index(){
$post = DB::table('posts')
->join('categories', 'posts.category_id', 'categories.id')
->leftJoin('subcategories', 'categories.id', 'subcategories.category_id')
->select('posts.*', 'categories.category_en', 'subcategories.subcategory_eng')
->orderBy('posts.id', 'desc')->paginate(5);
return view('backend.post.index', compact('post'));
}
add whereNull condition for parent id is null.
Please use leftjoin in your query:
public function Index(){
$post = DB::table('posts')
->join('categories', 'posts.category_id', 'categories.id')
->leftJoin('subcategories', 'posts.subcategory_id', 'subcategories.id')
->select('posts.*', 'categories.category_en', 'subcategories.subcategory_eng')
->orderBy('id', 'desc')->paginate(5);
return view('backend.post.index', compact('post'));
}
I have this DB:
[Database model]
This is the query I want to make in Laravel:
SELECT
product_translations.name,
product_translations.description,
products.ean_code
FROM product_translations, products, languages
WHERE product_translations.language_id = languages.id
AND products.id = product_translations.product_id
AND languages.language_code = "en";
Relationships in Laravel:
class Product extends Model
{
public function translations ()
{
return $this->hasMany(ProductTranslation::class, 'product_id');
}
}
class ProductTranslation extends Model
{
public function product()
{
return $this->belongsTo(Product::class, 'product_id');
}
public function language()
{
return $this->belongsTo(Language::class, 'language_id');
}
}
class Language extends Model
{
public function ProductTranslations()
{
return $this->hasMany(ProductTranslation::class, 'language_id');
}
}
is this correct? the raw query works.
thanks
The query syntax you are using is an old style syntax and will produce inner joins for tables. Using laravel you can use builtin methods to query data from your related models.
For your question I believe you need products list but with specific translation
$products = Product::with(['translations' => function($query)
{
$query->join('product_translations as pt', 'products.id', '=', 'pt.cart_id')
->join('languages as l', 'l.id', '=', 'pt.language_id')
->where('l.language_code', '=', 'en')
->first();
}])->get();
Or if you want to go with query builder you can write as
$products = DB::table('products AS p')
->select([
'p.id',
'p.is_organic',
'pt.name',
'pt.description',
'pt.ean_code'
])
->join('product_translations AS pt', 'pt.product_id', '=', 'p.id' )
->join('languages AS l', 'pt.language_id', '=', 'l.id')
->where('l.language_code','en')
->get();
In SQL
SELECT
p.id,
p.is_organic,
pt.name,
pt.description,
pt.ean_code
FROM products p
INNER JOIN product_translations as pt ON pt.product_id = p.id
INNER JOIN languages l ON pt.language_id = l.id
WHERE l.language_code = "en";
I'm having great difficulty in trying to convert the following query into an Eloquent one.
SELECT Sum(t.amount) AS amount,
m.name
FROM transactionsv2 t
JOIN channels c
ON t.entityid = c.uuid
JOIN merchants m
ON c.sender = m.uuid
WHERE t.paymenttype = 'DB'
AND t.status = 1
AND t.processing_time >= '2019-01-01'
AND t.processing_time < '2019-01-21'
GROUP BY m.name;
This is what I have but the result set is not right...
public function getTransactionsVolumeReport()
{
$report = Transaction::select(DB::raw('sum(amount) as amount, entityId'))
->where('paymentType', '=', 'DB')
->where('status', 1)
->where('processing_time', '>=', '2019-01-01 00:00:00')
->where('processing_time', '<=', '2019-01-21 23:59:59')
->with(['channel' => function ($q) {
$q->select('uuid', 'name', 'sender');
}])
->with(['channel.merchant' => function ($q) {
$q->select('uuid', 'name')
->groupBy('name');
}])
->get();
echo $report;
}
These are the queries that Laravel debugbar is showing...
Below are my Eloquent relationships...
Transaction Model
protected $with = ['channel', 'statusPayment'];
public function channel() {
return $this->hasOne(Channel::class, 'uuid', 'entityId');
}
-----
Channel Model
protected $with = ['merchant', 'attachedMerchantAccount'];
public function merchant() {
return $this->hasOne('App\Merchant', 'uuid', 'sender');
}
I am trying to do this query in Laravel 5.4 with Eloquent and I do not get the subquery to function as it should. This is the original SQL query:
select * from projects p
inner join projects_categories pc on p.id = pc.project_id
where pc.name in (select pc.name from projects p
inner join projects_categories pc on p.id = pc.project_id
where p.id = $project->id) and p.id <> $project->id;
This is what I'm trying to do:
Project::join('projects_categories', 'projects.id', '=', 'projects_categories.project_id')
->whereIn([
['projects_categories.name', function ($query) {
$query->select('projects_categories.name')
->from('projects')
->join('projects_categories', 'projects.id', '=', 'projects_categories.project_id')
->where('project.id', '=', $project->id);
}],
['projects.id', '<>', $project->id]
])
->get();
But all the time I get the error back:
Missing argument 2 for Illuminate\Database\Query\Builder::whereIn().
Could anyone help me with this? Thank you very much for your time and help.
Try this:
Project::join('projects_categories', 'projects.id', '=', 'projects_categories.project_id')
->whereIn('projects_categories.name', function($query) use($project) {
$query->select('projects_categories.name')->from('projects')
->join('projects_categories', 'projects.id', '=', 'projects_categories.project_id')
->where('projects.id', '=', $project->id);
})->where('projects.id', '<>', $project->id)->get();
If in Project.php you have a hasMany relationship for categories i.e
public function categories()
{
return $this->hasMany(Category::class);
}
Then you should be able to return the relationship eloquently like so:
Project::find($id)->with('categories');
Or if you already have a project object loaded
$project->load('categories');
I would checkout the Laravel documentation as the join you posted looks overly complicated!
I have the following relationship functions in my Job model:
public function resourceTypes(){
return $this->belongsToMany('ResourceType', 'job_requests');
}
public function resources(){
return $this->belongsToMany('Resource', 'jobs_resources')->withPivot('flow_type', 'resource_type_id');
}
I am able to get an object with data from both of the above relationships using:
$job = Job::findorfail($projectId);
$result = $job->with('resources.resourceTypes')->get();
I would like to put a where clause on the jobs_resources pivot table - specifically on the column flow_type.
How would I do this?
Try something like this:
$job = Job::with('resources' => function($q) {
$q->with('resourceTypes')->where('flow_type',2);
})->findorfail($projectId);
In above you will get only those resources with flow_type = 2
I ended up using the following statement:
Job::with(['resources' => function ($query){
$query->wherePivot('flow_type', '=', '1' );
}, 'resources.resourceTypes'])->where('id', $projectId)->firstOrFail();
$result = DB::table('job')
->join('job_resources', 'job.id', '=', 'job_resources.job_id')
->join('job_requests', 'job_resources.request_id', '=', 'job_requests.id')
->where('job_resources.flow_type', '=', CONDITION)
->get();
Your table data is not clear from your input, but this method (query builder) should work